001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.exportimport.lar;
016    
017    import aQute.bnd.annotation.ProviderType;
018    
019    import com.liferay.portal.kernel.util.CharPool;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.Validator;
023    import com.liferay.portal.model.StagedGroupedModel;
024    import com.liferay.portal.model.StagedModel;
025    import com.liferay.portal.util.PortletKeys;
026    
027    import java.io.Serializable;
028    
029    /**
030     * Provides utility methods for generating paths for entities being serialized
031     * with the portal's export/import framework.
032     *
033     * @author Mate Thurzo
034     * @author Daniel Kocsis
035     * @since  6.2
036     */
037    @ProviderType
038    public class ExportImportPathUtil {
039    
040            /**
041             * The company prefix used in generating paths.
042             */
043            public static final String PATH_PREFIX_COMPANY = "company";
044    
045            /**
046             * The group prefix used in generating paths.
047             */
048            public static final String PATH_PREFIX_GROUP = "group";
049    
050            /**
051             * @deprecated As of 7.0.0
052             */
053            @Deprecated
054            public static final String PATH_PREFIX_LAYOUT = "layout";
055    
056            /**
057             * The portlet prefix used in generating paths.
058             */
059            public static final String PATH_PREFIX_PORTLET = "portlet";
060    
061            /**
062             * The service prefix used in generating paths.
063             */
064            public static final String PATH_PREFIX_SERVICE = "service";
065    
066            public static String getCompanyModelPath(
067                    long companyId, String className, long classPK) {
068    
069                    return getModelPath(
070                            PATH_PREFIX_COMPANY, companyId, className, classPK, null);
071            }
072    
073            /**
074             * Returns the expando-specific path for the entity path. The entity path
075             * must include an XML file.
076             *
077             * <p>
078             * For example, if you had the entity path of
079             * <code>/group/10184/com.liferay.portlet.dynamicdatamapping.DDMStructure/10951.xml</code>,
080             * the returned expando-specific path would be the following:
081             * </p>
082             *
083             * <p>
084             * <pre>
085             * <code>
086             * /group/10184/com.liferay.portlet.dynamicdatamapping.DDMStructure/10951-expando.xml
087             * </code>
088             * </pre>
089             * </p>
090             *
091             * @param  path the previously generated entity path
092             * @return the expando-specific path for the entity path
093             */
094            public static String getExpandoPath(String path) {
095                    if (!Validator.isFilePath(path, false)) {
096                            throw new IllegalArgumentException(
097                                    path + " is located outside of the LAR");
098                    }
099    
100                    int pos = path.lastIndexOf(_FILE_EXTENSION_XML);
101    
102                    if (pos == -1) {
103                            throw new IllegalArgumentException(path + " is not an XML file");
104                    }
105    
106                    return path.substring(0, pos).concat("-expando").concat(
107                            path.substring(pos));
108            }
109    
110            /**
111             * @deprecated As of 7.0.0, replaced by {@link #getModelPath(StagedModel)}
112             */
113            @Deprecated
114            public static String getLayoutPath(
115                    PortletDataContext portletDataContext, long plid) {
116    
117                    StringBundler sb = new StringBundler(6);
118    
119                    sb.append(getRootPath(portletDataContext));
120                    sb.append(StringPool.FORWARD_SLASH);
121                    sb.append(PATH_PREFIX_LAYOUT);
122                    sb.append(StringPool.FORWARD_SLASH);
123                    sb.append(plid);
124                    sb.append(_FILE_EXTENSION_XML);
125    
126                    return sb.toString();
127            }
128    
129            /**
130             * Returns a model path based on the group ID, class name, and class PK.
131             *
132             * <p>
133             * For example, a model path would resemble the following:
134             * </p>
135             *
136             * <p>
137             * <pre>
138             * <code>
139             * /group/"groupId"/"className"/"classPK".xml
140             * </code>
141             * </pre>
142             * </p>
143             *
144             * @param  groupId the group ID of the entity's group
145             * @param  className the entity's class name
146             * @param  classPK the primary key of the entity
147             * @return a model path based on the parameters
148             */
149            public static String getModelPath(
150                    long groupId, String className, long classPK) {
151    
152                    return getModelPath(
153                            PATH_PREFIX_GROUP, groupId, className, classPK, null);
154            }
155    
156            /**
157             * Returns a model path based on the group ID, class name, and class PK,
158             * where the group ID is queried from the portlet data context. This method
159             * uses the source group ID from the context.
160             *
161             * <p>
162             * For example, a model path would resemble the following:
163             * </p>
164             *
165             * <p>
166             * <pre>
167             * <code>
168             * /group/"queried groupId"/"className"/"classPK".xml
169             * </code>
170             * </pre>
171             * </p>
172             *
173             * @param  portletDataContext the context of the current export/import
174             *         process
175             * @param  className the entity's class name
176             * @param  classPK the primary key of the entity
177             * @return a model path based on the parameters
178             * @see    PortletDataContext#getSourceGroupId()
179             */
180            public static String getModelPath(
181                    PortletDataContext portletDataContext, String className, long classPK) {
182    
183                    return getModelPath(portletDataContext, className, classPK, null);
184            }
185    
186            /**
187             * Returns a model path for the named file related to the entity, having the
188             * class name and class PK. The dependent object's file name is appended to
189             * the generated prefix.
190             *
191             * <p>
192             * For example, a model path would resemble the following:
193             * </p>
194             *
195             * <p>
196             * <pre>
197             * <code>
198             * /group/"queried groupId"/"className"/"classPK"/"dependentFileName"
199             * </code>
200             * </pre>
201             * </p>
202             *
203             * @param  portletDataContext the context of the current export/import
204             *         process
205             * @param  className the related entity's class name
206             * @param  classPK the primary key of the related entity
207             * @param  dependentFileName the dependent object's file name
208             * @return a model path for the entity's dependent object
209             */
210            public static String getModelPath(
211                    PortletDataContext portletDataContext, String className, long classPK,
212                    String dependentFileName) {
213    
214                    return getModelPath(
215                            PATH_PREFIX_GROUP, portletDataContext.getSourceGroupId(), className,
216                            classPK, dependentFileName);
217            }
218    
219            /**
220             * Returns a model path for the staged model. The group ID, class name, and
221             * class PK are queried from the staged model to generate the path.
222             *
223             * <p>
224             * For example, a model path would resemble the following:
225             * </p>
226             *
227             * <p>
228             * <pre>
229             * <code>
230             * /group/"queried groupId"/"queried className"/"queried classPK".xml
231             * </code>
232             * </pre>
233             * </p>
234             *
235             * @param  stagedModel the staged model the path is needed for
236             * @return a model path for the staged model
237             * @see    StagedModel
238             */
239            public static String getModelPath(StagedModel stagedModel) {
240                    return getModelPath(stagedModel, null);
241            }
242    
243            /**
244             * Returns a model path for the named file related to the staged model.
245             *
246             * <p>
247             * This method is useful, for example, for generating the path for an image
248             * related to a web content article. The staged model's attributes are used
249             * to generate the first part of the path; then the dependent object's file
250             * name is attached to the end of the path.
251             * </p>
252             *
253             * <p>
254             * For example, a model path would resemble the following:
255             * </p>
256             *
257             * <p>
258             * <pre>
259             * <code>
260             * /group/"queried groupId"/"queried className"/"queried classPK"/"dependentFileName"
261             * </code>
262             * </pre>
263             * </p>
264             *
265             * @param  stagedModel the staged model the path is needed for
266             * @param  dependentFileName the dependent object's file name
267             * @return a model path for the staged model's dependent object
268             */
269            public static String getModelPath(
270                    StagedModel stagedModel, String dependentFileName) {
271    
272                    StagedModelType stagedModelType = stagedModel.getStagedModelType();
273    
274                    if (stagedModel instanceof StagedGroupedModel) {
275                            StagedGroupedModel stagedGroupedModel =
276                                    (StagedGroupedModel)stagedModel;
277    
278                            return getModelPath(
279                                    PATH_PREFIX_GROUP, stagedGroupedModel.getGroupId(),
280                                    stagedModelType.getClassName(), stagedModel.getPrimaryKeyObj(),
281                                    dependentFileName);
282                    }
283                    else {
284                            return getModelPath(
285                                    PATH_PREFIX_COMPANY, stagedModel.getCompanyId(),
286                                    stagedModelType.getClassName(), stagedModel.getPrimaryKeyObj(),
287                                    dependentFileName);
288                    }
289            }
290    
291            /**
292             * Returns a portlet path for the portlet ID.
293             *
294             * <p>
295             * For example, a portlet path would resemble the following:
296             * </p>
297             *
298             * <p>
299             * <pre>
300             * <code>
301             * /group/"queried groupId"/portlet/"portletId"
302             * </code>
303             * </pre>
304             * </p>
305             *
306             * @param  portletDataContext the context of the current export/import
307             *         process
308             * @return a portlet path for the portlet ID
309             */
310            public static String getPortletPath(PortletDataContext portletDataContext) {
311                    return getPortletPath(
312                            portletDataContext, portletDataContext.getPortletId());
313            }
314    
315            /**
316             * Returns a portlet path for the portlet ID.
317             *
318             * <p>
319             * For example, a portlet path would resemble the following:
320             * </p>
321             *
322             * <p>
323             * <pre>
324             * <code>
325             * /group/"queried groupId"/portlet/"portletId"
326             * </code>
327             * </pre>
328             * </p>
329             *
330             * @param  portletDataContext the context of the current export/import
331             *         process
332             * @param  portletId the portlet ID the path is being generated for
333             * @return a portlet path for the portlet ID
334             */
335            public static String getPortletPath(
336                    PortletDataContext portletDataContext, String portletId) {
337    
338                    StringBundler sb = new StringBundler(5);
339    
340                    sb.append(getRootPath(portletDataContext));
341                    sb.append(StringPool.FORWARD_SLASH);
342                    sb.append(PATH_PREFIX_PORTLET);
343                    sb.append(StringPool.FORWARD_SLASH);
344                    sb.append(portletId);
345    
346                    return sb.toString();
347            }
348    
349            public static String getPortletPreferencesPath(
350                    PortletDataContext portletDataContext, String portletId, long ownerId,
351                    int ownerType, long plid) {
352    
353                    StringBundler sb = new StringBundler(8);
354    
355                    sb.append(getPortletPath(portletDataContext, portletId));
356                    sb.append("/preferences/");
357                    sb.append(getOwnerTypePath(ownerType));
358                    sb.append(ownerId);
359                    sb.append(CharPool.FORWARD_SLASH);
360                    sb.append(plid);
361                    sb.append(CharPool.FORWARD_SLASH);
362                    sb.append("portlet-preferences.xml");
363    
364                    return sb.toString();
365            }
366    
367            /**
368             * Returns a root path, or fragment, of the model path based on the scope
369             * group ID from the portlet data context.
370             *
371             * <p>
372             * For example, a root path would resemble the following:
373             * </p>
374             *
375             * <p>
376             * <pre>
377             * <code>
378             * /group/"queried groupId"
379             * </code>
380             * </pre>
381             * </p>
382             *
383             * @param  portletDataContext the context of the current export/import
384             *         process
385             * @return a root path, or fragment, of the model path
386             * @see    PortletDataContext#getScopeGroupId()
387             * @see    #getSourceRootPath(PortletDataContext)
388             */
389            public static String getRootPath(PortletDataContext portletDataContext) {
390                    return getRootPath(
391                            PATH_PREFIX_GROUP, portletDataContext.getScopeGroupId());
392            }
393    
394            public static String getServicePortletPreferencesPath(
395                    PortletDataContext portletDataContext, String serviceName, long ownerId,
396                    int ownerType) {
397    
398                    StringBundler sb = new StringBundler(9);
399    
400                    sb.append(getRootPath(portletDataContext));
401                    sb.append(StringPool.FORWARD_SLASH);
402                    sb.append(PATH_PREFIX_SERVICE);
403                    sb.append(StringPool.FORWARD_SLASH);
404                    sb.append(serviceName);
405                    sb.append(getOwnerTypePath(ownerType));
406                    sb.append(ownerId);
407                    sb.append(CharPool.FORWARD_SLASH);
408                    sb.append("portlet-preferences.xml");
409    
410                    return sb.toString();
411            }
412    
413            /**
414             * @deprecated As of 7.0.0, replaced by {@link
415             *             #getModelPath(PortletDataContext, String, long)}
416             */
417            @Deprecated
418            public static String getSourceLayoutPath(
419                    PortletDataContext portletDataContext, long layoutId) {
420    
421                    StringBundler sb = new StringBundler(5);
422    
423                    sb.append(getSourceRootPath(portletDataContext));
424                    sb.append(StringPool.FORWARD_SLASH);
425                    sb.append(PATH_PREFIX_LAYOUT);
426                    sb.append(StringPool.FORWARD_SLASH);
427                    sb.append(layoutId);
428    
429                    return sb.toString();
430            }
431    
432            /**
433             * @deprecated As of 7.0.0, with no direct replacement
434             */
435            @Deprecated
436            public static String getSourcePortletPath(
437                    PortletDataContext portletDataContext, String portletId) {
438    
439                    StringBundler sb = new StringBundler(5);
440    
441                    sb.append(getSourceRootPath(portletDataContext));
442                    sb.append(StringPool.FORWARD_SLASH);
443                    sb.append(PATH_PREFIX_PORTLET);
444                    sb.append(StringPool.FORWARD_SLASH);
445                    sb.append(portletId);
446    
447                    return sb.toString();
448            }
449    
450            /**
451             * Returns a source root path, or fragment, of the model path. This method
452             * is called by the {@link #getRootPath(PortletDataContext)} method. The
453             * fragment is generated with the source group ID from the portlet data
454             * context. This helper method is useful during the import process.
455             *
456             * <p>
457             * For example, a source root path would resemble the following:
458             * </p>
459             *
460             * <p>
461             * <pre>
462             * <code>
463             * /group/"queried groupId"
464             * </code>
465             * </pre>
466             * </p>
467             *
468             * @param  portletDataContext the context of the current export/import
469             *         process
470             * @return a path fragment
471             * @see    PortletDataContext#getSourceGroupId()
472             */
473            public static String getSourceRootPath(
474                    PortletDataContext portletDataContext) {
475    
476                    return getRootPath(
477                            PATH_PREFIX_GROUP, portletDataContext.getSourceGroupId());
478            }
479    
480            protected static String getModelPath(
481                    String pathPrefix, long pathPrimaryKey, String className,
482                    Serializable primaryKeyObj, String dependentFileName) {
483    
484                    StringBundler sb = new StringBundler(7);
485    
486                    sb.append(getRootPath(pathPrefix, pathPrimaryKey));
487                    sb.append(StringPool.FORWARD_SLASH);
488                    sb.append(className);
489                    sb.append(StringPool.FORWARD_SLASH);
490                    sb.append(primaryKeyObj.toString());
491    
492                    if (dependentFileName == null) {
493                            sb.append(_FILE_EXTENSION_XML);
494                    }
495                    else {
496                            sb.append(StringPool.FORWARD_SLASH);
497                            sb.append(dependentFileName);
498                    }
499    
500                    return sb.toString();
501            }
502    
503            protected static String getOwnerTypePath(int ownerType) {
504                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
505                            return "archived/";
506                    }
507                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
508                            return "company/";
509                    }
510                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
511                            return "group/";
512                    }
513                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
514                            return "layout/";
515                    }
516                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
517                            return "user/";
518                    }
519                    else {
520                            return StringPool.BLANK;
521                    }
522            }
523    
524            protected static String getRootPath(
525                    String pathPrefix, long pathPrimaryKey) {
526    
527                    StringBundler sb = new StringBundler(4);
528    
529                    sb.append(StringPool.FORWARD_SLASH);
530                    sb.append(pathPrefix);
531                    sb.append(StringPool.FORWARD_SLASH);
532                    sb.append(pathPrimaryKey);
533    
534                    return sb.toString();
535            }
536    
537            private static final String _FILE_EXTENSION_XML = ".xml";
538    
539    }