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         String properties = fileEntry.getLuceneProperties();
139 
140         List<DLFileVersion> dlFileVersions =
141             DLFileVersionLocalServiceUtil.getFileVersions(
142                 fileEntry.getFolderId(), fileName);
143 
144         if (dlFileVersions.isEmpty()) {
145             double versionNumber = Hook.DEFAULT_VERSION;
146             Date modifiedDate = fileEntry.getModifiedDate();
147 
148             migrateFile(
149                 companyId, portletId, groupId, repositoryId, fileName,
150                 versionNumber, properties, modifiedDate);
151 
152             return;
153         }
154 
155         for (DLFileVersion dlFileVersion : dlFileVersions) {
156             double versionNumber = dlFileVersion.getVersion();
157             Date modifiedDate = dlFileVersion.getCreateDate();
158 
159             migrateFile(
160                 companyId, portletId, groupId, repositoryId, fileName,
161                 versionNumber, properties, modifiedDate);
162         }
163     }
164 
165     protected void migrateFile(
166         long companyId, String portletId, long groupId, long repositoryId,
167         String fileName, double versionNumber, String properties,
168         Date modifiedDate) {
169 
170         try {
171             InputStream is = _sourceHook.getFileAsStream(
172                 companyId, repositoryId, fileName, versionNumber);
173 
174             if (versionNumber == Hook.DEFAULT_VERSION) {
175                 _targetHook.addFile(
176                     companyId, portletId, groupId, repositoryId, fileName,
177                     properties, modifiedDate, _tagsEntries, is);
178             }
179             else {
180                 _targetHook.updateFile(
181                     companyId, portletId, groupId, repositoryId, fileName,
182                     versionNumber, fileName, properties, modifiedDate,
183                     _tagsEntries, is);
184             }
185         }
186         catch (Exception e) {
187             _log.error("Migration failed for " + fileName, e);
188         }
189     }
190     protected void migrateFiles(
191             long companyId, String dirName, String[] fileNames)
192         throws Exception {
193 
194         String portletId = CompanyConstants.SYSTEM_STRING;
195         long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
196         long repositoryId = CompanyConstants.SYSTEM;
197         double versionNumber = Hook.DEFAULT_VERSION;
198         String properties = StringPool.BLANK;
199         Date modifiedDate = new Date();
200 
201         try {
202             _targetHook.addDirectory(companyId, repositoryId, dirName);
203         }
204         catch (DuplicateDirectoryException dde) {
205         }
206 
207         for (String fileName : fileNames) {
208             if (fileName.startsWith(StringPool.SLASH)) {
209                 fileName = fileName.substring(1);
210             }
211 
212             migrateFile(
213                 companyId, portletId, groupId, repositoryId, fileName,
214                 versionNumber, properties, modifiedDate);
215         }
216     }
217 
218     protected void migrateMB() throws Exception {
219         int count = MBMessageLocalServiceUtil.getMBMessagesCount();
220         int pages = count / Indexer.DEFAULT_INTERVAL;
221 
222         MaintenanceUtil.appendStatus(
223             "Migrating message boards attachments in " + count + " messages");
224 
225         for (int i = 0; i <= pages; i++) {
226             int start = (i * Indexer.DEFAULT_INTERVAL);
227             int end = start + Indexer.DEFAULT_INTERVAL;
228 
229             List<MBMessage> messages =
230                 MBMessageLocalServiceUtil.getMBMessages(start, end);
231 
232             for (MBMessage message : messages) {
233                 migrateFiles(
234                     message.getCompanyId(), message.getAttachmentsDir(),
235                     message.getAttachmentsFiles());
236             }
237         }
238     }
239 
240     protected void migratePortlets() throws Exception {
241         migrateDL();
242         migrateMB();
243         migrateWiki();
244     }
245 
246     protected void migrateWiki() throws Exception {
247         int count = WikiPageLocalServiceUtil.getWikiPagesCount();
248         int pages = count / Indexer.DEFAULT_INTERVAL;
249 
250         MaintenanceUtil.appendStatus(
251             "Migrating wiki page attachments in " + count + " pages");
252 
253         for (int i = 0; i <= pages; i++) {
254             int start = (i * Indexer.DEFAULT_INTERVAL);
255             int end = start + Indexer.DEFAULT_INTERVAL;
256 
257             List<WikiPage> wikiPages =
258                 WikiPageLocalServiceUtil.getWikiPages(start, end);
259 
260             for (WikiPage wikiPage : wikiPages) {
261                 if (!wikiPage.isHead()) {
262                     continue;
263                 }
264 
265                 migrateFiles(
266                     wikiPage.getCompanyId(), wikiPage.getAttachmentsDir(),
267                     wikiPage.getAttachmentsFiles());
268             }
269         }
270     }
271 
272     private static final String[] _HOOKS = new String[] {
273         "com.liferay.documentlibrary.util.AdvancedFileSystemHook",
274         "com.liferay.documentlibrary.util.CMISHook",
275         "com.liferay.documentlibrary.util.FileSystemHook",
276         "com.liferay.documentlibrary.util.JCRHook",
277         "com.liferay.documentlibrary.util.S3Hook"
278     };
279 
280     private static Log _log = LogFactoryUtil.getLog(
281         ConvertDocumentLibrary.class);
282 
283     private Hook _sourceHook;
284     private String[] _tagsEntries = new String[0];
285     private Hook _targetHook;
286 
287 }