001
014
015 package com.liferay.portal.convert;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.search.Indexer;
020 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
021 import com.liferay.portal.kernel.util.PropsKeys;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.kernel.workflow.WorkflowConstants;
025 import com.liferay.portal.model.CompanyConstants;
026 import com.liferay.portal.util.MaintenanceUtil;
027 import com.liferay.portal.util.PropsValues;
028 import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
029 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
030 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
031 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
032 import com.liferay.portlet.documentlibrary.store.AdvancedFileSystemStore;
033 import com.liferay.portlet.documentlibrary.store.CMISStore;
034 import com.liferay.portlet.documentlibrary.store.FileSystemStore;
035 import com.liferay.portlet.documentlibrary.store.JCRStore;
036 import com.liferay.portlet.documentlibrary.store.S3Store;
037 import com.liferay.portlet.documentlibrary.store.Store;
038 import com.liferay.portlet.documentlibrary.store.StoreFactory;
039 import com.liferay.portlet.messageboards.model.MBMessage;
040 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
041 import com.liferay.portlet.wiki.model.WikiPage;
042 import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
043
044 import java.io.InputStream;
045
046 import java.util.List;
047
048
052 public class ConvertDocumentLibrary extends ConvertProcess {
053
054 @Override
055 public String getDescription() {
056 return "migrate-documents-from-one-repository-to-another";
057 }
058
059 @Override
060 public String getParameterDescription() {
061 return "please-select-a-new-repository-hook";
062 }
063
064 @Override
065 public String[] getParameterNames() {
066 StringBundler sb = new StringBundler(_HOOKS.length * 2 + 2);
067
068 sb.append(PropsKeys.DL_STORE_IMPL);
069 sb.append(StringPool.EQUAL);
070
071 for (String hook : _HOOKS) {
072 if (!hook.equals(PropsValues.DL_STORE_IMPL)) {
073 sb.append(hook);
074 sb.append(StringPool.SEMICOLON);
075 }
076 }
077
078 return new String[] {sb.toString()};
079 }
080
081 @Override
082 public boolean isEnabled() {
083 return true;
084 }
085
086 @Override
087 protected void doConvert() throws Exception {
088 _sourceStore = StoreFactory.getInstance();
089
090 String[] values = getParameterValues();
091
092 String targetStoreClassName = values[0];
093
094 ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
095
096 _targetStore = (Store)classLoader.loadClass(
097 targetStoreClassName).newInstance();
098
099 migratePortlets();
100
101 StoreFactory.setInstance(_targetStore);
102
103 MaintenanceUtil.appendStatus(
104 "Please set " + PropsKeys.DL_STORE_IMPL +
105 " in your portal-ext.properties to use " +
106 targetStoreClassName);
107
108 PropsValues.DL_STORE_IMPL = targetStoreClassName;
109 }
110
111 protected void migrateDL() throws Exception {
112 int count = DLFileEntryLocalServiceUtil.getFileEntriesCount();
113 int pages = count / Indexer.DEFAULT_INTERVAL;
114
115 MaintenanceUtil.appendStatus(
116 "Migrating " + count + " document library files");
117
118 for (int i = 0; i <= pages; i++) {
119 int start = (i * Indexer.DEFAULT_INTERVAL);
120 int end = start + Indexer.DEFAULT_INTERVAL;
121
122 List<DLFileEntry> dlFileEntries =
123 DLFileEntryLocalServiceUtil.getFileEntries(start, end);
124
125 for (DLFileEntry dlFileEntry : dlFileEntries) {
126 long companyId = dlFileEntry.getCompanyId();
127 long repositoryId = dlFileEntry.getDataRepositoryId();
128
129 migrateDLFileEntry(companyId, repositoryId, dlFileEntry);
130 }
131 }
132 }
133
134 protected void migrateDLFileEntry(
135 long companyId, long repositoryId, DLFileEntry fileEntry)
136 throws Exception {
137
138 String fileName = fileEntry.getName();
139
140 List<DLFileVersion> dlFileVersions = fileEntry.getFileVersions(
141 WorkflowConstants.STATUS_ANY);
142
143 if (dlFileVersions.isEmpty()) {
144 String versionNumber = Store.VERSION_DEFAULT;
145
146 migrateFile(companyId, repositoryId, fileName, versionNumber);
147
148 return;
149 }
150
151 for (DLFileVersion dlFileVersion : dlFileVersions) {
152 String versionNumber = dlFileVersion.getVersion();
153
154 migrateFile(companyId, repositoryId, fileName, versionNumber);
155 }
156 }
157
158 protected void migrateFile(
159 long companyId, long repositoryId, String fileName,
160 String versionNumber) {
161
162 try {
163 InputStream is = _sourceStore.getFileAsStream(
164 companyId, repositoryId, fileName, versionNumber);
165
166 if (versionNumber.equals(Store.VERSION_DEFAULT)) {
167 _targetStore.addFile(companyId, repositoryId, fileName, is);
168 }
169 else {
170 _targetStore.updateFile(
171 companyId, repositoryId, fileName, versionNumber, is);
172 }
173 }
174 catch (Exception e) {
175 _log.error("Migration failed for " + fileName, e);
176 }
177 }
178
179 protected void migrateFiles(
180 long companyId, String dirName, String[] fileNames)
181 throws Exception {
182
183 long repositoryId = CompanyConstants.SYSTEM;
184 String versionNumber = Store.VERSION_DEFAULT;
185
186 try {
187 _targetStore.addDirectory(companyId, repositoryId, dirName);
188 }
189 catch (DuplicateDirectoryException dde) {
190 }
191
192 for (String fileName : fileNames) {
193 if (fileName.startsWith(StringPool.SLASH)) {
194 fileName = fileName.substring(1);
195 }
196
197 migrateFile(companyId, repositoryId, fileName, versionNumber);
198 }
199 }
200
201 protected void migrateMB() throws Exception {
202 int count = MBMessageLocalServiceUtil.getMBMessagesCount();
203 int pages = count / Indexer.DEFAULT_INTERVAL;
204
205 MaintenanceUtil.appendStatus(
206 "Migrating message boards attachments in " + count + " messages");
207
208 for (int i = 0; i <= pages; i++) {
209 int start = (i * Indexer.DEFAULT_INTERVAL);
210 int end = start + Indexer.DEFAULT_INTERVAL;
211
212 List<MBMessage> messages =
213 MBMessageLocalServiceUtil.getMBMessages(start, end);
214
215 for (MBMessage message : messages) {
216 migrateFiles(
217 message.getCompanyId(), message.getAttachmentsDir(),
218 message.getAttachmentsFiles());
219 }
220 }
221 }
222
223 protected void migratePortlets() throws Exception {
224 migrateDL();
225 migrateMB();
226 migrateWiki();
227 }
228
229 protected void migrateWiki() throws Exception {
230 int count = WikiPageLocalServiceUtil.getWikiPagesCount();
231 int pages = count / Indexer.DEFAULT_INTERVAL;
232
233 MaintenanceUtil.appendStatus(
234 "Migrating wiki page attachments in " + count + " pages");
235
236 for (int i = 0; i <= pages; i++) {
237 int start = (i * Indexer.DEFAULT_INTERVAL);
238 int end = start + Indexer.DEFAULT_INTERVAL;
239
240 List<WikiPage> wikiPages =
241 WikiPageLocalServiceUtil.getWikiPages(start, end);
242
243 for (WikiPage wikiPage : wikiPages) {
244 if (!wikiPage.isHead()) {
245 continue;
246 }
247
248 migrateFiles(
249 wikiPage.getCompanyId(), wikiPage.getAttachmentsDir(),
250 wikiPage.getAttachmentsFiles());
251 }
252 }
253 }
254
255 private static final String[] _HOOKS = new String[] {
256 AdvancedFileSystemStore.class.getName(), CMISStore.class.getName(),
257 FileSystemStore.class.getName(), JCRStore.class.getName(),
258 S3Store.class.getName()
259 };
260
261 private static Log _log = LogFactoryUtil.getLog(
262 ConvertDocumentLibrary.class);
263
264 private Store _sourceStore;
265 private Store _targetStore;
266
267 }