/* * #%L * Alfresco Records Management Module * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * - * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * - * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.module.org_alfresco_module_rm.script; import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.admin.CustomMetadataException; import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementCustomModel; import org.alfresco.service.namespace.QName; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import org.springframework.extensions.surf.util.URLDecoder; import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; /** * Implementation for Java backed webscript to add RM custom property definitions * to the custom model. * * @author Neil McErlean */ public class CustomPropertyDefinitionPost extends BaseCustomPropertyWebScript { protected RecordsManagementAdminService rmAdminService; private static final String PARAM_DATATYPE = "dataType"; private static final String PARAM_TITLE = "title"; private static final String PARAM_DESCRIPTION = "description"; private static final String PARAM_DEFAULT_VALUE = "defaultValue"; private static final String PARAM_MULTI_VALUED = "multiValued"; private static final String PARAM_MANDATORY = "mandatory"; private static final String PARAM_PROTECTED = "protected"; private static final String PARAM_CONSTRAINT_REF = "constraintRef"; private static final String PARAM_ELEMENT = "element"; private static final String PARAM_LABEL = "label"; private static final String PROP_ID = "propId"; private static final String MESSAGE = "errorMessage"; private static final String URL = "url"; public void setRecordsManagementAdminService(RecordsManagementAdminService rmAdminService) { this.rmAdminService = rmAdminService; } @Override protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) { JSONObject json = null; Map<String, Object> ftlModel = null; try { json = new JSONObject(new JSONTokener(req.getContent().getContent())); try { ftlModel = createPropertyDefinition(req, json); } catch (CustomMetadataException e) { status.setCode(Status.STATUS_BAD_REQUEST); ftlModel = new HashMap<String, Object>(); ftlModel.put(MESSAGE, e.getMessage()); } } catch (IOException iox) { throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from req.", iox); } catch (JSONException je) { throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from req.", je); } return ftlModel; } /** * Applies custom properties. * @throws CustomMetadataException */ protected Map<String, Object> createPropertyDefinition(WebScriptRequest req, JSONObject json) throws JSONException, CustomMetadataException { Map<String, Object> result = new HashMap<String, Object>(); Map<String, Serializable> params = getParamsFromUrlAndJson(req, json); QName propertyQName = createNewPropertyDefinition(params); String localName = propertyQName.getLocalName(); result.put(PROP_ID, localName); String urlResult = req.getServicePath() + "/" + propertyQName.getLocalName(); result.put(URL, urlResult); return result; } @SuppressWarnings("rawtypes") protected Map<String, Serializable> getParamsFromUrlAndJson(WebScriptRequest req, JSONObject json) throws JSONException { Map<String, Serializable> params; params = new HashMap<String, Serializable>(); params.put(PARAM_ELEMENT, req.getParameter(PARAM_ELEMENT)); for (Iterator iter = json.keys(); iter.hasNext(); ) { String nextKeyString = (String)iter.next(); String nextValueString = json.getString(nextKeyString); params.put(nextKeyString, nextValueString); } return params; } /** * Create a property definition based on the parameter values provided * * @param params parameter values * @return {@link QName} qname of the newly created custom property * @throws CustomMetadataException */ protected QName createNewPropertyDefinition(Map<String, Serializable> params) throws CustomMetadataException { // Get the customisable type name String customisableElement = (String)params.get(PARAM_ELEMENT); QName customisableType = mapToTypeQName(customisableElement); String label = URLDecoder.decode((String)params.get(PARAM_LABEL)); //According to the wireframes, type here can only be date|text|number Serializable serializableParam = params.get(PARAM_DATATYPE); QName type = null; if (serializableParam != null) { if (serializableParam instanceof String) { type = QName.createQName((String)serializableParam, getNamespaceService()); } else if (serializableParam instanceof QName) { type = (QName)serializableParam; } else { throw new AlfrescoRuntimeException("Unexpected type of dataType param: "+serializableParam+" (expected String or QName)"); } } // The title is actually generated, so this parameter will be ignored // by the RMAdminService String title = (String)params.get(PARAM_TITLE); String description = (String)params.get(PARAM_DESCRIPTION); String defaultValue = (String)params.get(PARAM_DEFAULT_VALUE); boolean mandatory = false; serializableParam = params.get(PARAM_MANDATORY); if (serializableParam != null) { mandatory = Boolean.valueOf(serializableParam.toString()); } boolean isProtected = false; serializableParam = params.get(PARAM_PROTECTED); if (serializableParam != null) { isProtected = Boolean.valueOf(serializableParam.toString()); } boolean multiValued = false; serializableParam = params.get(PARAM_MULTI_VALUED); if (serializableParam != null) { multiValued = Boolean.valueOf(serializableParam.toString()); } serializableParam = params.get(PARAM_CONSTRAINT_REF); QName constraintRef = null; if (serializableParam != null) { if (serializableParam instanceof String) { constraintRef = QName.createQName((String)serializableParam, getNamespaceService()); } else if (serializableParam instanceof QName) { constraintRef = (QName)serializableParam; } else { throw new AlfrescoRuntimeException("Unexpected type of constraintRef param: "+serializableParam+" (expected String or QName)"); } } // if propId is specified, use it. QName proposedQName = null; String propId = (String)params.get(PROP_ID); if (propId != null) { proposedQName = QName.createQName(RecordsManagementCustomModel.RM_CUSTOM_PREFIX, propId, getNamespaceService()); } return rmAdminService.addCustomPropertyDefinition( proposedQName, customisableType, label, type, title, description, defaultValue, multiValued, mandatory, isProtected, constraintRef); } }