1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.convert;
16  
17  import com.liferay.documentlibrary.DuplicateDirectoryException;
18  import com.liferay.documentlibrary.util.Hook;
19  import com.liferay.documentlibrary.util.HookFactory;
20  import com.liferay.portal.kernel.log.Log;
21  import com.liferay.portal.kernel.log.LogFactoryUtil;
22  import com.liferay.portal.kernel.search.Indexer;
23  import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
24  import com.liferay.portal.kernel.util.PropsKeys;
25  import com.liferay.portal.kernel.util.StringBundler;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.model.CompanyConstants;
28  import com.liferay.portal.model.GroupConstants;
29  import com.liferay.portal.util.MaintenanceUtil;
30  import com.liferay.portal.util.PortletKeys;
31  import com.liferay.portal.util.PropsValues;
32  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
33  import com.liferay.portlet.documentlibrary.model.DLFileVersion;
34  import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
35  import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
36  import com.liferay.portlet.messageboards.model.MBMessage;
37  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
38  import com.liferay.portlet.wiki.model.WikiPage;
39  import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
40  
41  import java.io.InputStream;
42  
43  import java.util.Date;
44  import java.util.List;
45  
46  /**
47   * <a href="ConvertDocumentLibrary.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Minhchau Dang
50   * @author Alexander Chow
51   */
52  public class ConvertDocumentLibrary extends ConvertProcess {
53  
54      public String getDescription() {
55          return "migrate-documents-from-one-repository-to-another";
56      }
57  
58      public String getParameterDescription() {
59          return "please-select-a-new-repository-hook";
60      }
61  
62      public String[] getParameterNames() {
63          StringBundler sb = new StringBundler(_HOOKS.length * 2 + 2);
64  
65          sb.append(PropsKeys.DL_HOOK_IMPL);
66          sb.append(StringPool.EQUAL);
67  
68          for (String hook : _HOOKS) {
69              if (!hook.equals(PropsValues.DL_HOOK_IMPL)) {
70                  sb.append(hook);
71                  sb.append(StringPool.SEMICOLON);
72              }
73          }
74  
75          return new String[] {sb.toString()};
76      }
77  
78      public boolean isEnabled() {
79          return true;
80      }
81  
82      protected void doConvert() throws Exception {
83          _sourceHook = HookFactory.getInstance();
84  
85          String[] values = getParameterValues();
86  
87          String targetHookClassName = values[0];
88  
89          ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
90  
91          _targetHook = (Hook)classLoader.loadClass(
92              targetHookClassName).newInstance();
93  
94          migratePortlets();
95  
96          HookFactory.setInstance(_targetHook);
97  
98          MaintenanceUtil.appendStatus(
99              "Please set " + PropsKeys.DL_HOOK_IMPL +
100                 " in your portal-ext.properties to use " + targetHookClassName);
101 
102         PropsValues.DL_HOOK_IMPL = targetHookClassName;
103     }
104 
105     protected void migrateDL() throws Exception {
106         int count = DLFileEntryLocalServiceUtil.getDLFileEntriesCount();
107         int pages = count / Indexer.DEFAULT_INTERVAL;
108 
109         MaintenanceUtil.appendStatus(
110             "Migrating " + count + " document library files");
111 
112         for (int i = 0; i <= pages; i++) {
113             int start = (i * Indexer.DEFAULT_INTERVAL);
114             int end = start + Indexer.DEFAULT_INTERVAL;
115 
116             List<DLFileEntry> dlFileEntries =
117                 DLFileEntryLocalServiceUtil.getDLFileEntries(start, end);
118 
119             String portletId = PortletKeys.DOCUMENT_LIBRARY;
120 
121             for (DLFileEntry dlFileEntry : dlFileEntries) {
122                 long companyId = dlFileEntry.getCompanyId();
123                 long groupId = dlFileEntry.getGroupId();
124                 long repositoryId = dlFileEntry.getFolderId();
125 
126                 migrateDLFileEntry(
127                     companyId, portletId, groupId, repositoryId, dlFileEntry);
128             }
129         }
130     }
131 
132     protected void migrateDLFileEntry(
133             long companyId, String portletId, long groupId, long repositoryId,
134             DLFileEntry fileEntry)
135         throws Exception {
136 
137         String fileName = fileEntry.getName();
138         long fileEntryId = fileEntry.getFileEntryId();
139         String properties = fileEntry.getLuceneProperties();
140 
141         List<DLFileVersion> dlFileVersions =
142             DLFileVersionLocalServiceUtil.getFileVersions(
143                 fileEntry.getFolderId(), fileName);
144 
145         if (dlFileVersions.isEmpty()) {
146             double versionNumber = Hook.DEFAULT_VERSION;
147             Date modifiedDate = fileEntry.getModifiedDate();
148 
149             migrateFile(
150                 companyId, portletId, groupId, repositoryId, fileName,
151                 versionNumber, fileEntryId, properties, modifiedDate);
152 
153             return;
154         }
155 
156         for (DLFileVersion dlFileVersion : dlFileVersions) {
157             double versionNumber = dlFileVersion.getVersion();
158             Date modifiedDate = dlFileVersion.getCreateDate();
159 
160             migrateFile(
161                 companyId, portletId, groupId, repositoryId, fileName,
162                 versionNumber, fileEntryId, properties, modifiedDate);
163         }
164     }
165 
166     protected void migrateFile(
167         long companyId, String portletId, long groupId, long repositoryId,
168         String fileName, double versionNumber, long fileEntryId,
169         String properties, Date modifiedDate) {
170 
171         try {
172             InputStream is = _sourceHook.getFileAsStream(
173                 companyId, repositoryId, fileName, versionNumber);
174 
175             if (versionNumber == Hook.DEFAULT_VERSION) {
176                 _targetHook.addFile(
177                     companyId, portletId, groupId, repositoryId, fileName,
178                     fileEntryId, properties, modifiedDate, _tagsCategories,
179                     _tagsEntries, is);
180             }
181             else {
182                 _targetHook.updateFile(
183                     companyId, portletId, groupId, repositoryId, fileName,
184                     versionNumber, fileName, fileEntryId, properties,
185                     modifiedDate, _tagsCategories, _tagsEntries, is);
186             }
187         }
188         catch (Exception e) {
189             _log.error("Migration failed for " + fileName, e);
190         }
191     }
192     protected void migrateFiles(
193             long companyId, String dirName, String[] fileNames)
194         throws Exception {
195 
196         String portletId = CompanyConstants.SYSTEM_STRING;
197         long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
198         long repositoryId = CompanyConstants.SYSTEM;
199         double versionNumber = Hook.DEFAULT_VERSION;
200         long fileEntryId = 0;
201         String properties = StringPool.BLANK;
202         Date modifiedDate = new Date();
203 
204         try {
205             _targetHook.addDirectory(companyId, repositoryId, dirName);
206         }
207         catch (DuplicateDirectoryException dde) {
208         }
209 
210         for (String fileName : fileNames) {
211             if (fileName.startsWith(StringPool.SLASH)) {
212                 fileName = fileName.substring(1);
213             }
214 
215             migrateFile(
216                 companyId, portletId, groupId, repositoryId, fileName,
217                 versionNumber, fileEntryId, properties, modifiedDate);
218         }
219     }
220 
221     protected void migrateMB() throws Exception {
222         int count = MBMessageLocalServiceUtil.getMBMessagesCount();
223         int pages = count / Indexer.DEFAULT_INTERVAL;
224 
225         MaintenanceUtil.appendStatus(
226             "Migrating message boards attachments in " + count + " messages");
227 
228         for (int i = 0; i <= pages; i++) {
229             int start = (i * Indexer.DEFAULT_INTERVAL);
230             int end = start + Indexer.DEFAULT_INTERVAL;
231 
232             List<MBMessage> messages =
233                 MBMessageLocalServiceUtil.getMBMessages(start, end);
234 
235             for (MBMessage message : messages) {
236                 migrateFiles(
237                     message.getCompanyId(), message.getAttachmentsDir(),
238                     message.getAttachmentsFiles());
239             }
240         }
241     }
242 
243     protected void migratePortlets() throws Exception {
244         migrateDL();
245         migrateMB();
246         migrateWiki();
247     }
248 
249     protected void migrateWiki() throws Exception {
250         int count = WikiPageLocalServiceUtil.getWikiPagesCount();
251         int pages = count / Indexer.DEFAULT_INTERVAL;
252 
253         MaintenanceUtil.appendStatus(
254             "Migrating wiki page attachments in " + count + " pages");
255 
256         for (int i = 0; i <= pages; i++) {
257             int start = (i * Indexer.DEFAULT_INTERVAL);
258             int end = start + Indexer.DEFAULT_INTERVAL;
259 
260             List<WikiPage> wikiPages =
261                 WikiPageLocalServiceUtil.getWikiPages(start, end);
262 
263             for (WikiPage wikiPage : wikiPages) {
264                 if (!wikiPage.isHead()) {
265                     continue;
266                 }
267 
268                 migrateFiles(
269                     wikiPage.getCompanyId(), wikiPage.getAttachmentsDir(),
270                     wikiPage.getAttachmentsFiles());
271             }
272         }
273     }
274 
275     private static final String[] _HOOKS = new String[] {
276         "com.liferay.documentlibrary.util.AdvancedFileSystemHook",
277         "com.liferay.documentlibrary.util.CMISHook",
278         "com.liferay.documentlibrary.util.FileSystemHook",
279         "com.liferay.documentlibrary.util.JCRHook",
280         "com.liferay.documentlibrary.util.S3Hook"
281     };
282 
283     private static Log _log = LogFactoryUtil.getLog(
284         ConvertDocumentLibrary.class);
285 
286     private Hook _sourceHook;
287     private String[] _tagsCategories = new String[0];
288     private String[] _tagsEntries = new String[0];
289     private Hook _targetHook;
290 
291 }