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