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 _odfRefTableHelper.saxItems(contentHandler, contentAttributeDefinition); 116 } 117 else if (StringUtils.isNotEmpty(contentAttributeDefinition.getContentTypeId())) 118 { 119 _saxContents(contentAttributeDefinition); 120 } 121 } 122 } 123 else 124 { 125 // no attribute definition found or no attribute path has been defined 126 XMLUtils.startElement(contentHandler, "items"); 127 XMLUtils.endElement(contentHandler, "items"); 128 } 129 130 } 131 catch (Exception e) 132 { 133 throw new ProcessingException("Error retrieving the values of metadata '" + attributePath + "'", e); 134 } 135 136 contentHandler.endDocument(); 137 } 138 139 /** 140 * Get the element definition from its path. 141 * @param cType the content type. 142 * @param attributePath the attribute path. 143 * @return the element definition or null if not found. 144 */ 145 protected ElementDefinition _getElementDefinition(ContentType cType, String attributePath) 146 { 147 if (StringUtils.isNotEmpty(attributePath)) 148 { 149 if (cType.hasModelItem(attributePath)) 150 { 151 ModelItem modelItem = cType.getModelItem(attributePath); 152 if (modelItem instanceof ElementDefinition) 153 { 154 return (ElementDefinition) modelItem; 155 } 156 else 157 { 158 getLogger().warn("The attribute path '" + attributePath + "' does refers an element definition"); 159 } 160 } 161 else 162 { 163 getLogger().warn("There is no attribute defined at path '" + attributePath + "' for content type '" + cType.getId() + "'."); 164 } 165 166 } 167 168 // no attribute definition found or no attribute path has been defined 169 return null; 170 } 171 172 /** 173 * SAX contents of the type defined by the attribute definition 174 * @param attributeDefinition The attribute definition 175 * @throws SAXException if an error occurred while saxing 176 */ 177 protected void _saxContents(ContentAttributeDefinition attributeDefinition) throws SAXException 178 { 179 AttributesImpl attrs = new AttributesImpl(); 180 attrs.addCDATAAttribute("metadataName", attributeDefinition.getName()); 181 attrs.addCDATAAttribute("metadataPath", attributeDefinition.getPath()); 182 attrs.addCDATAAttribute("contentTypeId", attributeDefinition.getContentTypeId()); 183 XMLUtils.startElement(contentHandler, "items", attrs); 184 185 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, attributeDefinition.getContentTypeId()); 186 187 String xpathQuery = ContentQueryHelper.getContentXPathQuery(cTypeExpr); 188 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 189 190 for (Content content : contents) 191 { 192 AttributesImpl valueAttrs = new AttributesImpl(); 193 valueAttrs.addCDATAAttribute("id", content.getId()); 194 XMLUtils.createElement(contentHandler, "item", valueAttrs, content.getTitle()); 195 } 196 197 XMLUtils.endElement(contentHandler, "items"); 198 } 199 200}