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