001    /**
002     * Copyright (c) 2000-2013 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.portal.kernel.lar;
016    
017    import com.liferay.portal.NoSuchModelException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.trash.TrashHandler;
023    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
024    import com.liferay.portal.kernel.util.ArrayUtil;
025    import com.liferay.portal.kernel.util.GetterUtil;
026    import com.liferay.portal.kernel.workflow.WorkflowConstants;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.model.StagedModel;
029    import com.liferay.portal.model.TrashedModel;
030    import com.liferay.portal.model.WorkflowedModel;
031    
032    import java.util.HashMap;
033    import java.util.Map;
034    
035    /**
036     * @author Mate Thurzo
037     * @author Daniel Kocsis
038     * @author Zsolt Berentey
039     */
040    public abstract class BaseStagedModelDataHandler<T extends StagedModel>
041            implements StagedModelDataHandler<T> {
042    
043            @Override
044            public abstract void deleteStagedModel(
045                            String uuid, long groupId, String className, String extraData)
046                    throws PortalException, SystemException;
047    
048            @Override
049            public void exportStagedModel(
050                            PortletDataContext portletDataContext, T stagedModel)
051                    throws PortletDataException {
052    
053                    validateExport(portletDataContext, stagedModel);
054    
055                    String path = ExportImportPathUtil.getModelPath(stagedModel);
056    
057                    if (portletDataContext.isPathExportedInScope(path)) {
058                            return;
059                    }
060    
061                    try {
062                            ManifestSummary manifestSummary =
063                                    portletDataContext.getManifestSummary();
064    
065                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
066                                    "stagedModel", stagedModel, manifestSummary);
067    
068                            doExportStagedModel(portletDataContext, (T)stagedModel.clone());
069    
070                            if (countStagedModel(portletDataContext, stagedModel)) {
071                                    manifestSummary.incrementModelAdditionCount(
072                                            stagedModel.getStagedModelType());
073                            }
074                    }
075                    catch (PortletDataException pde) {
076                            throw pde;
077                    }
078                    catch (Exception e) {
079                            PortletDataException pde = new PortletDataException(e);
080    
081                            if (e instanceof NoSuchModelException) {
082                                    pde.setStagedModel(stagedModel);
083                                    pde.setType(PortletDataException.MISSING_DEPENDENCY);
084                            }
085    
086                            throw pde;
087                    }
088            }
089    
090            @Override
091            public abstract String[] getClassNames();
092    
093            @Override
094            public String getDisplayName(T stagedModel) {
095                    return stagedModel.getUuid();
096            }
097    
098            @Override
099            public int[] getExportableStatuses() {
100                    return new int[] {WorkflowConstants.STATUS_APPROVED};
101            }
102    
103            @Override
104            public Map<String, String> getReferenceAttributes(
105                    PortletDataContext portletDataContext, T stagedModel) {
106    
107                    return new HashMap<String, String>();
108            }
109    
110            @Override
111            public void importCompanyStagedModel(
112                            PortletDataContext portletDataContext, Element element)
113                    throws PortletDataException {
114    
115                    String uuid = element.attributeValue("uuid");
116                    long classPK = GetterUtil.getLong(element.attributeValue("class-pk"));
117    
118                    importCompanyStagedModel(portletDataContext, uuid, classPK);
119            }
120    
121            @Override
122            public void importCompanyStagedModel(
123                            PortletDataContext portletDataContext, String uuid, long classPK)
124                    throws PortletDataException {
125    
126                    try {
127                            doImportCompanyStagedModel(portletDataContext, uuid, classPK);
128                    }
129                    catch (PortletDataException pde) {
130                            throw pde;
131                    }
132                    catch (Exception e) {
133                            throw new PortletDataException(e);
134                    }
135            }
136    
137            @Override
138            public void importStagedModel(
139                            PortletDataContext portletDataContext, T stagedModel)
140                    throws PortletDataException {
141    
142                    String path = ExportImportPathUtil.getModelPath(stagedModel);
143    
144                    if (portletDataContext.isPathProcessed(path)) {
145                            return;
146                    }
147    
148                    try {
149                            ManifestSummary manifestSummary =
150                                    portletDataContext.getManifestSummary();
151    
152                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
153                                    "stagedModel", stagedModel, manifestSummary);
154    
155                            if (stagedModel instanceof TrashedModel) {
156                                    restoreStagedModel(portletDataContext, stagedModel);
157                            }
158    
159                            doImportStagedModel(portletDataContext, stagedModel);
160    
161                            manifestSummary.incrementModelAdditionCount(
162                                    stagedModel.getStagedModelType());
163                    }
164                    catch (PortletDataException pde) {
165                            throw pde;
166                    }
167                    catch (Exception e) {
168                            throw new PortletDataException(e);
169                    }
170            }
171    
172            @Override
173            public void restoreStagedModel(
174                            PortletDataContext portletDataContext, T stagedModel)
175                    throws PortletDataException {
176    
177                    try {
178                            doRestoreStagedModel(portletDataContext, stagedModel);
179                    }
180                    catch (PortletDataException pde) {
181                            throw pde;
182                    }
183                    catch (Exception e) {
184                            throw new PortletDataException(e);
185                    }
186            }
187    
188            @Override
189            public boolean validateReference(
190                    PortletDataContext portletDataContext, Element referenceElement) {
191    
192                    String uuid = referenceElement.attributeValue("uuid");
193    
194                    try {
195                            boolean valid = validateMissingReference(
196                                    uuid, portletDataContext.getCompanyId(),
197                                    portletDataContext.getScopeGroupId());
198    
199                            if (!valid) {
200                                    valid = validateMissingReference(
201                                            uuid, portletDataContext.getCompanyId(),
202                                            portletDataContext.getCompanyGroupId());
203                            }
204    
205                            return valid;
206                    }
207                    catch (Exception e) {
208                            return false;
209                    }
210            }
211    
212            protected boolean countStagedModel(
213                    PortletDataContext portletDataContext, T stagedModel) {
214    
215                    return !portletDataContext.isStagedModelCounted(stagedModel);
216            }
217    
218            protected abstract void doExportStagedModel(
219                            PortletDataContext portletDataContext, T stagedModel)
220                    throws Exception;
221    
222            protected void doImportCompanyStagedModel(
223                            PortletDataContext portletDataContext, String uuid, long classPK)
224                    throws Exception {
225    
226                    throw new UnsupportedOperationException();
227            }
228    
229            protected abstract void doImportStagedModel(
230                            PortletDataContext portletDataContext, T stagedModel)
231                    throws Exception;
232    
233            protected void doRestoreStagedModel(
234                            PortletDataContext portletDataContext, T stagedModel)
235                    throws Exception {
236    
237                    throw new UnsupportedOperationException();
238            }
239    
240            protected void validateExport(
241                            PortletDataContext portletDataContext, T stagedModel)
242                    throws PortletDataException {
243    
244                    if (stagedModel instanceof WorkflowedModel) {
245                            WorkflowedModel workflowedModel = (WorkflowedModel)stagedModel;
246    
247                            if (!ArrayUtil.contains(
248                                            getExportableStatuses(), workflowedModel.getStatus())) {
249    
250                                    PortletDataException pde = new PortletDataException(
251                                            PortletDataException.STATUS_UNAVAILABLE);
252    
253                                    pde.setStagedModel(stagedModel);
254    
255                                    throw pde;
256                            }
257                    }
258    
259                    StagedModelType stagedModelType = stagedModel.getStagedModelType();
260    
261                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
262                            stagedModelType.getClassName());
263    
264                    if (trashHandler != null) {
265                            try {
266                                    long classPK = (Long)stagedModel.getPrimaryKeyObj();
267    
268                                    if (trashHandler.isInTrash(classPK)) {
269                                            PortletDataException pde = new PortletDataException(
270                                                    PortletDataException.STATUS_IN_TRASH);
271    
272                                            pde.setStagedModel(stagedModel);
273    
274                                            throw pde;
275                                    }
276                            }
277                            catch (PortletDataException pde) {
278                                    throw pde;
279                            }
280                            catch (Exception e) {
281                                    if (_log.isWarnEnabled()) {
282                                            _log.warn(
283                                                    "Unable to check trash status for " +
284                                                            stagedModel.getModelClassName());
285                                    }
286                            }
287                    }
288            }
289    
290            protected boolean validateMissingReference(
291                            String uuid, long companyId, long groupId)
292                    throws Exception {
293    
294                    return true;
295            }
296    
297            private static Log _log = LogFactoryUtil.getLog(
298                    BaseStagedModelDataHandler.class);
299    
300    }