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