001
014
015 package com.liferay.portal.convert;
016
017 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
018 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.Property;
020 import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.exception.SystemException;
023 import com.liferay.portal.kernel.log.Log;
024 import com.liferay.portal.kernel.log.LogFactoryUtil;
025 import com.liferay.portal.kernel.repository.model.FileEntry;
026 import com.liferay.portal.kernel.util.InstanceFactory;
027 import com.liferay.portal.kernel.util.ListUtil;
028 import com.liferay.portal.kernel.util.PropsKeys;
029 import com.liferay.portal.kernel.util.StringBundler;
030 import com.liferay.portal.kernel.util.StringPool;
031 import com.liferay.portal.kernel.workflow.WorkflowConstants;
032 import com.liferay.portal.model.Image;
033 import com.liferay.portal.service.ImageLocalServiceUtil;
034 import com.liferay.portal.service.persistence.ImageActionableDynamicQuery;
035 import com.liferay.portal.util.ClassLoaderUtil;
036 import com.liferay.portal.util.MaintenanceUtil;
037 import com.liferay.portal.util.PropsValues;
038 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
039 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
040 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
041 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
042 import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryActionableDynamicQuery;
043 import com.liferay.portlet.documentlibrary.store.AdvancedFileSystemStore;
044 import com.liferay.portlet.documentlibrary.store.CMISStore;
045 import com.liferay.portlet.documentlibrary.store.DBStore;
046 import com.liferay.portlet.documentlibrary.store.FileSystemStore;
047 import com.liferay.portlet.documentlibrary.store.JCRStore;
048 import com.liferay.portlet.documentlibrary.store.S3Store;
049 import com.liferay.portlet.documentlibrary.store.Store;
050 import com.liferay.portlet.documentlibrary.store.StoreFactory;
051 import com.liferay.portlet.documentlibrary.util.comparator.FileVersionVersionComparator;
052 import com.liferay.portlet.messageboards.model.MBMessage;
053 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
054 import com.liferay.portlet.messageboards.service.persistence.MBMessageActionableDynamicQuery;
055 import com.liferay.portlet.wiki.model.WikiPage;
056 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
057 import com.liferay.portlet.wiki.service.persistence.WikiPageActionableDynamicQuery;
058
059 import java.io.InputStream;
060
061 import java.util.List;
062
063
067 public class ConvertDocumentLibrary extends ConvertProcess {
068
069 @Override
070 public String getDescription() {
071 return "migrate-documents-from-one-repository-to-another";
072 }
073
074 @Override
075 public String getParameterDescription() {
076 return "please-select-a-new-repository-hook";
077 }
078
079 @Override
080 public String[] getParameterNames() {
081 StringBundler sb = new StringBundler(_HOOKS.length * 2 + 2);
082
083 sb.append(PropsKeys.DL_STORE_IMPL);
084 sb.append(StringPool.EQUAL);
085
086 for (String hook : _HOOKS) {
087 if (!hook.equals(PropsValues.DL_STORE_IMPL)) {
088 sb.append(hook);
089 sb.append(StringPool.SEMICOLON);
090 }
091 }
092
093 return new String[] {sb.toString()};
094 }
095
096 @Override
097 public boolean isEnabled() {
098 return true;
099 }
100
101 @Override
102 protected void doConvert() throws Exception {
103 _sourceStore = StoreFactory.getInstance();
104
105 String[] values = getParameterValues();
106
107 String targetStoreClassName = values[0];
108
109 _targetStore = (Store)InstanceFactory.newInstance(
110 ClassLoaderUtil.getPortalClassLoader(), targetStoreClassName);
111
112 migratePortlets();
113
114 StoreFactory.setInstance(_targetStore);
115
116 MaintenanceUtil.appendStatus(
117 "Please set " + PropsKeys.DL_STORE_IMPL +
118 " in your portal-ext.properties to use " +
119 targetStoreClassName);
120
121 PropsValues.DL_STORE_IMPL = targetStoreClassName;
122 }
123
124 protected List<DLFileVersion> getDLFileVersions(DLFileEntry dlFileEntry)
125 throws SystemException {
126
127 List<DLFileVersion> dlFileVersions = dlFileEntry.getFileVersions(
128 WorkflowConstants.STATUS_ANY);
129
130 return ListUtil.sort(
131 dlFileVersions, new FileVersionVersionComparator(true));
132 }
133
134 protected void migrateDL() throws PortalException, SystemException {
135 int count = DLFileEntryLocalServiceUtil.getFileEntriesCount();
136
137 MaintenanceUtil.appendStatus(
138 "Migrating " + count + " documents and media files");
139
140 ActionableDynamicQuery actionableDynamicQuery =
141 new DLFileEntryActionableDynamicQuery() {
142
143 @Override
144 protected void addCriteria(DynamicQuery dynamicQuery) {
145 Property classNameIdProperty = PropertyFactoryUtil.forName(
146 "classNameId");
147
148 dynamicQuery.add(classNameIdProperty.eq(0L));
149 }
150
151 @Override
152 protected void performAction(Object object) throws SystemException {
153 DLFileEntry dlFileEntry = (DLFileEntry)object;
154
155 migrateDLFileEntry(
156 dlFileEntry.getCompanyId(),
157 dlFileEntry.getDataRepositoryId(), dlFileEntry);
158 }
159
160 };
161
162 actionableDynamicQuery.performActions();
163 }
164
165 protected void migrateDLFileEntry(
166 long companyId, long repositoryId, DLFileEntry dlFileEntry)
167 throws SystemException {
168
169 String fileName = dlFileEntry.getName();
170
171 List<DLFileVersion> dlFileVersions = getDLFileVersions(dlFileEntry);
172
173 if (dlFileVersions.isEmpty()) {
174 String versionNumber = Store.VERSION_DEFAULT;
175
176 migrateFile(companyId, repositoryId, fileName, versionNumber);
177
178 return;
179 }
180
181 for (DLFileVersion dlFileVersion : dlFileVersions) {
182 String versionNumber = dlFileVersion.getVersion();
183
184 migrateFile(companyId, repositoryId, fileName, versionNumber);
185 }
186 }
187
188 protected void migrateFile(
189 long companyId, long repositoryId, String fileName,
190 String versionNumber) {
191
192 try {
193 InputStream is = _sourceStore.getFileAsStream(
194 companyId, repositoryId, fileName, versionNumber);
195
196 if (versionNumber.equals(Store.VERSION_DEFAULT)) {
197 _targetStore.addFile(companyId, repositoryId, fileName, is);
198 }
199 else {
200 _targetStore.updateFile(
201 companyId, repositoryId, fileName, versionNumber, is);
202 }
203 }
204 catch (Exception e) {
205 _log.error("Migration failed for " + fileName, e);
206 }
207 }
208
209 protected void migrateImages() throws PortalException, SystemException {
210 int count = ImageLocalServiceUtil.getImagesCount();
211
212 MaintenanceUtil.appendStatus("Migrating " + count + " images");
213
214 ActionableDynamicQuery actionableDynamicQuery =
215 new ImageActionableDynamicQuery() {
216
217 @Override
218 protected void performAction(Object object) {
219 Image image = (Image)object;
220
221 String fileName =
222 image.getImageId() + StringPool.PERIOD + image.getType();
223
224 migrateFile(0, 0, fileName, Store.VERSION_DEFAULT);
225 }
226
227 };
228
229 actionableDynamicQuery.performActions();
230 }
231
232 protected void migrateMB() throws PortalException, SystemException {
233 int count = MBMessageLocalServiceUtil.getMBMessagesCount();
234
235 MaintenanceUtil.appendStatus(
236 "Migrating message boards attachments in " + count + " messages");
237
238 ActionableDynamicQuery actionableDynamicQuery =
239 new MBMessageActionableDynamicQuery() {
240
241 @Override
242 protected void performAction(Object object)
243 throws PortalException, SystemException {
244
245 MBMessage mbMessage = (MBMessage)object;
246
247 for (FileEntry fileEntry :
248 mbMessage.getAttachmentsFileEntries()) {
249
250 DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
251
252 migrateDLFileEntry(
253 mbMessage.getCompanyId(),
254 DLFolderConstants.getDataRepositoryId(
255 dlFileEntry.getRepositoryId(),
256 dlFileEntry.getFolderId()),
257 dlFileEntry);
258 }
259 }
260
261 };
262
263 actionableDynamicQuery.performActions();
264 }
265
266 protected void migratePortlets() throws Exception {
267 migrateImages();
268 migrateDL();
269 migrateMB();
270 migrateWiki();
271 }
272
273 protected void migrateWiki() throws PortalException, SystemException {
274 int count = WikiPageLocalServiceUtil.getWikiPagesCount();
275
276 MaintenanceUtil.appendStatus(
277 "Migrating wiki page attachments in " + count + " pages");
278
279 ActionableDynamicQuery actionableDynamicQuery =
280 new WikiPageActionableDynamicQuery() {
281
282 @Override
283 protected void addCriteria(DynamicQuery dynamicQuery) {
284 Property property = PropertyFactoryUtil.forName("head");
285
286 dynamicQuery.add(property.eq(true));
287 }
288
289 @Override
290 protected void performAction(Object object) throws SystemException {
291 WikiPage wikiPage = (WikiPage)object;
292
293 for (FileEntry fileEntry :
294 wikiPage.getAttachmentsFileEntries()) {
295
296 DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
297
298 migrateDLFileEntry(
299 wikiPage.getCompanyId(),
300 DLFolderConstants.getDataRepositoryId(
301 dlFileEntry.getRepositoryId(),
302 dlFileEntry.getFolderId()),
303 dlFileEntry);
304 }
305 }
306
307 };
308
309 actionableDynamicQuery.performActions();
310 }
311
312 private static final String[] _HOOKS = new String[] {
313 AdvancedFileSystemStore.class.getName(), CMISStore.class.getName(),
314 DBStore.class.getName(), FileSystemStore.class.getName(),
315 JCRStore.class.getName(), S3Store.class.getName()
316 };
317
318 private static Log _log = LogFactoryUtil.getLog(
319 ConvertDocumentLibrary.class);
320
321 private Store _sourceStore;
322 private Store _targetStore;
323
324 }