001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.convert;
016    
017    import com.liferay.documentlibrary.DuplicateDirectoryException;
018    import com.liferay.documentlibrary.util.Hook;
019    import com.liferay.documentlibrary.util.HookFactory;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.search.Indexer;
023    import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.workflow.WorkflowConstants;
028    import com.liferay.portal.model.CompanyConstants;
029    import com.liferay.portal.model.GroupConstants;
030    import com.liferay.portal.service.ServiceContext;
031    import com.liferay.portal.util.MaintenanceUtil;
032    import com.liferay.portal.util.PortletKeys;
033    import com.liferay.portal.util.PropsValues;
034    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
035    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
036    import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
037    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
038    import com.liferay.portlet.messageboards.model.MBMessage;
039    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
040    import com.liferay.portlet.wiki.model.WikiPage;
041    import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
042    
043    import java.io.InputStream;
044    
045    import java.util.Date;
046    import java.util.List;
047    
048    /**
049     * @author Minhchau Dang
050     * @author Alexander Chow
051     */
052    public class ConvertDocumentLibrary extends ConvertProcess {
053    
054            public String getDescription() {
055                    return "migrate-documents-from-one-repository-to-another";
056            }
057    
058            public String getParameterDescription() {
059                    return "please-select-a-new-repository-hook";
060            }
061    
062            public String[] getParameterNames() {
063                    StringBundler sb = new StringBundler(_HOOKS.length * 2 + 2);
064    
065                    sb.append(PropsKeys.DL_HOOK_IMPL);
066                    sb.append(StringPool.EQUAL);
067    
068                    for (String hook : _HOOKS) {
069                            if (!hook.equals(PropsValues.DL_HOOK_IMPL)) {
070                                    sb.append(hook);
071                                    sb.append(StringPool.SEMICOLON);
072                            }
073                    }
074    
075                    return new String[] {sb.toString()};
076            }
077    
078            public boolean isEnabled() {
079                    return true;
080            }
081    
082            protected void doConvert() throws Exception {
083                    _sourceHook = HookFactory.getInstance();
084    
085                    String[] values = getParameterValues();
086    
087                    String targetHookClassName = values[0];
088    
089                    ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
090    
091                    _targetHook = (Hook)classLoader.loadClass(
092                            targetHookClassName).newInstance();
093    
094                    migratePortlets();
095    
096                    HookFactory.setInstance(_targetHook);
097    
098                    MaintenanceUtil.appendStatus(
099                            "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.getRepositoryId();
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                                    groupId, repositoryId, fileName, WorkflowConstants.STATUS_ANY);
144    
145                    if (dlFileVersions.isEmpty()) {
146                            String 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                            String 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, String 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.equals(Hook.DEFAULT_VERSION)) {
176                                    _targetHook.addFile(
177                                            companyId, portletId, groupId, repositoryId, fileName,
178                                            fileEntryId, properties, modifiedDate, _serviceContext,
179                                            is);
180                            }
181                            else {
182                                    _targetHook.updateFile(
183                                            companyId, portletId, groupId, repositoryId, fileName,
184                                            versionNumber, fileName, fileEntryId, properties,
185                                            modifiedDate, _serviceContext, 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                    String 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 ServiceContext _serviceContext = new ServiceContext();
287            private Hook _sourceHook;
288            private Hook _targetHook;
289    
290    }