001/* 002 * Copyright 2013 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.cms.contenttype; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.LinkedHashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.avalon.framework.parameters.Parameters; 026import org.apache.cocoon.ProcessingException; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.Redirector; 029import org.apache.cocoon.environment.Request; 030import org.apache.cocoon.environment.SourceResolver; 031 032import org.ametys.cms.content.GetMetadataSetDefAction; 033import org.ametys.core.cocoon.JSonReader; 034 035/** 036 * Get metadata set definition as JSON object from a given content type. 037 * Be careful, this action is only based on a single content type and a metadata set. 038 * All metadata of the asked metadata set are returned regardless of the current content and user's rights 039 */ 040public class GetMetadataSetDefByContentTypeAction extends GetMetadataSetDefAction 041{ 042 @Override 043 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 044 { 045 Request request = ObjectModelHelper.getRequest(objectModel); 046 047 boolean isEditionMetadataSet = parameters.getParameterAsBoolean("isEditionMetadataSet", false); 048 String metadataSetName = parameters.getParameter("metadataSetName", "main"); 049 String contentTypeId = parameters.getParameter("contentTypeId"); 050 051 Map<String, Object> jsonObject = new HashMap<>(); 052 053 List<String> languages = getLanguages(request); 054 055 ContentType contentType = _contentTypeExtensionPoint.getExtension(contentTypeId); 056 jsonObject.put("contentType", contentType2Json(contentType, metadataSetName, isEditionMetadataSet, languages)); 057 058 request.setAttribute(JSonReader.OBJECT_TO_READ, jsonObject); 059 return EMPTY_MAP; 060 } 061 062 /** 063 * Convert content to JSON object 064 * @param contentType The content type 065 * @param metadataSetName The metadata set name 066 * @param isEditionMetadataSet true if it is metadataset for edition 067 * @param languages the current languages requested by the client (an ordonned list) 068 * @return The JSON object representing the content 069 * @throws ProcessingException if an error occurred 070 */ 071 protected Map<String, Object> contentType2Json (ContentType contentType, String metadataSetName, boolean isEditionMetadataSet, List<String> languages) throws ProcessingException 072 { 073 Map<String, Object> jsonObject = new LinkedHashMap<>(); 074 075 jsonObject.put("id", contentType.getId()); 076 jsonObject.put("title", contentType.getLabel()); 077 jsonObject.put("defaultTitle", contentType.getDefaultTitle()); 078 079 MetadataSet metadataSet = null; 080 081 if (isEditionMetadataSet) 082 { 083 metadataSet = contentType.getMetadataSetForEdition(metadataSetName); 084 } 085 else 086 { 087 metadataSet = contentType.getMetadataSetForView(metadataSetName); 088 } 089 090 jsonObject.put("metadataSetName", metadataSetName); 091 jsonObject.put("isEditionMetadataSet", isEditionMetadataSet); 092 093 if (metadataSet == null) 094 { 095 _logger.warn("Unknown metadata set '{}' of type '{}' for content type(s) '{}'", 096 metadataSetName, isEditionMetadataSet ? "edition" : "view", contentType.getId()); 097 } 098 else 099 { 100 jsonObject.put("metadataSet", metadataSetElement2JsonObject(contentType, null, metadataSet, languages)); 101 } 102 103 104 return jsonObject; 105 } 106 107 /** 108 * Convert {@link AbstractMetadataSetElement} to JSON object 109 * @param contentType The content type 110 * @param metadataDefinition The metadata definition 111 * @param metadataSetElement The metadataset element 112 * @param languages the current languages requested by the client (an ordonned list) 113 * @return The JSON object representing the metadataset element 114 * @throws ProcessingException If an error occured 115 */ 116 protected Map<String, Object> metadataSetElement2JsonObject(ContentType contentType, MetadataDefinition metadataDefinition, AbstractMetadataSetElement metadataSetElement, List<String> languages) throws ProcessingException 117 { 118 Map<String, Object> jsonObject = new LinkedHashMap<>(); 119 120 for (AbstractMetadataSetElement subMetadataSetElement : metadataSetElement.getElements()) 121 { 122 if (subMetadataSetElement instanceof MetadataDefinitionReference) 123 { 124 MetadataDefinitionReference metadataDefRef = (MetadataDefinitionReference) subMetadataSetElement; 125 String metadataName = metadataDefRef.getMetadataName(); 126 MetadataDefinition metaDef = _getMetadataDefinition(contentType, metadataDefinition, metadataName); 127 128 if (metaDef == null) 129 { 130 throw new IllegalArgumentException("Unable to get the metadata definition of metadata \"" + metadataName + "\""); 131 } 132 133 String metadataPath = metaDef.getId(); 134 jsonObject.put(metaDef.getName(), metadataDefinition2JsonObject(null, metadataDefRef, metaDef, metadataPath, new HashSet<>(), languages)); 135 } 136 else 137 { 138 if (!jsonObject.containsKey("fieldsets")) 139 { 140 jsonObject.put("fieldsets", new ArrayList<Map<String, Object>>()); 141 } 142 143 @SuppressWarnings("unchecked") 144 List<Map<String, Object>> fieldsets = (List<Map<String, Object>>) jsonObject.get("fieldsets"); 145 146 Fieldset fieldset = (Fieldset) subMetadataSetElement; 147 148 Map<String, Object> fieldSetObject = new LinkedHashMap<>(); 149 fieldSetObject.put("role", fieldset.getRole()); 150 fieldSetObject.put("label", fieldset.getLabel()); 151 fieldSetObject.put("elements", metadataSetElement2JsonObject(contentType, metadataDefinition, fieldset, languages)); 152 153 fieldsets.add(fieldSetObject); 154 } 155 } 156 157 return jsonObject; 158 } 159 160 /** 161 * Retrieves a sub metadata definition from a content type or a parent metadata definition. 162 * @param contentType the content type. 163 * @param parentMetadataDefinition the parent metadata definition. 164 * @param metadataName the metadata name. 165 * @return the metadata definition found or <code>null</code> otherwise. 166 */ 167 protected MetadataDefinition _getMetadataDefinition(ContentType contentType, MetadataDefinition parentMetadataDefinition, String metadataName) 168 { 169 MetadataDefinition metadataDefinition = null; 170 171 if (parentMetadataDefinition == null) 172 { 173 metadataDefinition = contentType.getMetadataDefinition(metadataName); 174 } 175 else 176 { 177 metadataDefinition = parentMetadataDefinition.getMetadataDefinition(metadataName); 178 } 179 180 return metadataDefinition; 181 } 182}