001/* 002 * Copyright 2014 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.odf.enumeration; 017 018import java.io.IOException; 019import java.util.Map; 020 021import org.apache.avalon.framework.service.ServiceException; 022import org.apache.avalon.framework.service.ServiceManager; 023import org.apache.cocoon.ProcessingException; 024import org.apache.cocoon.generation.ServiceableGenerator; 025import org.apache.cocoon.xml.AttributesImpl; 026import org.apache.cocoon.xml.XMLUtils; 027import org.apache.commons.lang3.StringUtils; 028import org.xml.sax.SAXException; 029 030import org.ametys.cms.contenttype.ContentAttributeDefinition; 031import org.ametys.cms.contenttype.ContentType; 032import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 033import org.ametys.cms.repository.Content; 034import org.ametys.cms.repository.ContentQueryHelper; 035import org.ametys.cms.repository.ContentTypeExpression; 036import org.ametys.odf.program.ProgramFactory; 037import org.ametys.plugins.repository.AmetysObjectIterable; 038import org.ametys.plugins.repository.AmetysObjectResolver; 039import org.ametys.plugins.repository.query.expression.Expression.Operator; 040import org.ametys.runtime.i18n.I18nizableText; 041import org.ametys.runtime.model.ElementDefinition; 042import org.ametys.runtime.model.Enumerator; 043import org.ametys.runtime.model.ModelItem; 044 045/** 046 * Generate the values of an enumerated attribute of the program content type. 047 */ 048public class EnumeratedAttributeValuesGenerator extends ServiceableGenerator 049{ 050 /** The name of the parameter containing the path of the enumerated attribute */ 051 protected static final String ATTRIBUTE_PATH_PARAMETER_NAME = "attributePath"; 052 053 /** The content type extension point. */ 054 protected ContentTypeExtensionPoint _cTypeEP; 055 /** The ODf enumeration helper */ 056 protected OdfReferenceTableHelper _odfRefTableHelper; 057 /** The Ametys resolver */ 058 protected AmetysObjectResolver _resolver; 059 060 @Override 061 public void service(ServiceManager serviceManager) throws ServiceException 062 { 063 super.service(serviceManager); 064 _cTypeEP = (ContentTypeExtensionPoint) serviceManager.lookup(ContentTypeExtensionPoint.ROLE); 065 _odfRefTableHelper = (OdfReferenceTableHelper) serviceManager.lookup(OdfReferenceTableHelper.ROLE); 066 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 067 } 068 069 @Override 070 public void generate() throws IOException, SAXException, ProcessingException 071 { 072 ContentType programCType = _cTypeEP.getExtension(ProgramFactory.PROGRAM_CONTENT_TYPE); 073 074 String attributePath = parameters.getParameter(ATTRIBUTE_PATH_PARAMETER_NAME, StringUtils.EMPTY); 075 076 contentHandler.startDocument(); 077 078 try 079 { 080 ElementDefinition elementDefinition = _getElementDefinition(programCType, attributePath); 081 if (elementDefinition != null) 082 { 083 Enumerator enumerator = elementDefinition.getEnumerator(); 084 if (enumerator != null) 085 { 086 AttributesImpl attrs = new AttributesImpl(); 087 attrs.addCDATAAttribute("metadataName", elementDefinition.getName()); 088 attrs.addCDATAAttribute("metadataPath", elementDefinition.getPath()); 089 XMLUtils.startElement(contentHandler, "items", attrs); 090 091 Map<Object, I18nizableText> entries = enumerator.getTypedEntries(); 092 for (Object code : entries.keySet()) 093 { 094 String codeStr = code.toString(); 095 if (StringUtils.isNotEmpty(codeStr)) 096 { 097 I18nizableText value = entries.get(code); 098 099 AttributesImpl valueAttrs = new AttributesImpl(); 100 valueAttrs.addCDATAAttribute("code", codeStr); 101 102 XMLUtils.startElement(contentHandler, "item", valueAttrs); 103 value.toSAX(contentHandler); 104 XMLUtils.endElement(contentHandler, "item"); 105 } 106 } 107 108 XMLUtils.endElement(contentHandler, "items"); 109 } 110 else if (elementDefinition instanceof ContentAttributeDefinition) 111 { 112 ContentAttributeDefinition contentAttributeDefinition = (ContentAttributeDefinition) elementDefinition; 113 if (_odfRefTableHelper.isTableReference(contentAttributeDefinition.getContentTypeId())) 114 { 115 String lang = parameters.getParameter("lang", null); 116 117 _odfRefTableHelper.saxItems(contentHandler, contentAttributeDefinition, lang); 118 } 119 else if (StringUtils.isNotEmpty(contentAttributeDefinition.getContentTypeId())) 120 { 121 _saxContents(contentAttributeDefinition); 122 } 123 } 124 } 125 else 126 { 127 // no attribute definition found or no attribute path has been defined 128 XMLUtils.startElement(contentHandler, "items"); 129 XMLUtils.endElement(contentHandler, "items"); 130 } 131 132 } 133 catch (Exception e) 134 { 135 throw new ProcessingException("Error retrieving the values of metadata '" + attributePath + "'", e); 136 } 137 138 contentHandler.endDocument(); 139 } 140 141 /** 142 * Get the element definition from its path. 143 * @param cType the content type. 144 * @param attributePath the attribute path. 145 * @return the element definition or null if not found. 146 */ 147 protected ElementDefinition _getElementDefinition(ContentType cType, String attributePath) 148 { 149 if (StringUtils.isNotEmpty(attributePath)) 150 { 151 if (cType.hasModelItem(attributePath)) 152 { 153 ModelItem modelItem = cType.getModelItem(attributePath); 154 if (modelItem instanceof ElementDefinition) 155 { 156 return (ElementDefinition) modelItem; 157 } 158 else 159 { 160 getLogger().warn("The attribute path '" + attributePath + "' does refers an element definition"); 161 } 162 } 163 else 164 { 165 getLogger().warn("There is no attribute defined at path '" + attributePath + "' for content type '" + cType.getId() + "'."); 166 } 167 168 } 169 170 // no attribute definition found or no attribute path has been defined 171 return null; 172 } 173 174 /** 175 * SAX contents of the type defined by the attribute definition 176 * @param attributeDefinition The attribute definition 177 * @throws SAXException if an error occurred while saxing 178 */ 179 protected void _saxContents(ContentAttributeDefinition attributeDefinition) throws SAXException 180 { 181 AttributesImpl attrs = new AttributesImpl(); 182 attrs.addCDATAAttribute("metadataName", attributeDefinition.getName()); 183 attrs.addCDATAAttribute("metadataPath", attributeDefinition.getPath()); 184 attrs.addCDATAAttribute("contentTypeId", attributeDefinition.getContentTypeId()); 185 XMLUtils.startElement(contentHandler, "items", attrs); 186 187 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, attributeDefinition.getContentTypeId()); 188 189 String xpathQuery = ContentQueryHelper.getContentXPathQuery(cTypeExpr); 190 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 191 192 for (Content content : contents) 193 { 194 AttributesImpl valueAttrs = new AttributesImpl(); 195 valueAttrs.addCDATAAttribute("id", content.getId()); 196 XMLUtils.createElement(contentHandler, "item", valueAttrs, content.getTitle()); 197 } 198 199 XMLUtils.endElement(contentHandler, "items"); 200 } 201 202}