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.lang.StringUtils; 028import org.xml.sax.SAXException; 029 030import org.ametys.cms.contenttype.ContentType; 031import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 032import org.ametys.cms.contenttype.MetadataDefinition; 033import org.ametys.cms.contenttype.MetadataType; 034import org.ametys.cms.repository.Content; 035import org.ametys.cms.repository.ContentQueryHelper; 036import org.ametys.cms.repository.ContentTypeExpression; 037import org.ametys.odf.program.ProgramFactory; 038import org.ametys.plugins.repository.AmetysObjectIterable; 039import org.ametys.plugins.repository.AmetysObjectResolver; 040import org.ametys.plugins.repository.query.expression.Expression.Operator; 041import org.ametys.runtime.i18n.I18nizableText; 042import org.ametys.runtime.parameter.Enumerator; 043 044/** 045 * Generate the values of an enumerated metadata of the program content type. 046 */ 047public class EnumeratedMetadataValuesGenerator extends ServiceableGenerator 048{ 049 /** The content type extension point. */ 050 protected ContentTypeExtensionPoint _cTypeEP; 051 /** The ODf enumeration helper */ 052 protected OdfReferenceTableHelper _odfRefTableHelper; 053 /** The Ametys resolver */ 054 protected AmetysObjectResolver _resolver; 055 056 @Override 057 public void service(ServiceManager serviceManager) throws ServiceException 058 { 059 super.service(serviceManager); 060 _cTypeEP = (ContentTypeExtensionPoint) serviceManager.lookup(ContentTypeExtensionPoint.ROLE); 061 _odfRefTableHelper = (OdfReferenceTableHelper) serviceManager.lookup(OdfReferenceTableHelper.ROLE); 062 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 063 } 064 065 @Override 066 public void generate() throws IOException, SAXException, ProcessingException 067 { 068 ContentType programCType = _cTypeEP.getExtension(ProgramFactory.PROGRAM_CONTENT_TYPE); 069 070 String metadataPath = parameters.getParameter("metadataPath", ""); 071 072 contentHandler.startDocument(); 073 074 try 075 { 076 MetadataDefinition metaDef = _getMetadataDefinition(programCType, metadataPath); 077 if (metaDef != null) 078 { 079 Enumerator enumerator = metaDef.getEnumerator(); 080 if (enumerator != null) 081 { 082 AttributesImpl attrs = new AttributesImpl(); 083 attrs.addCDATAAttribute("metadataName", metaDef.getName()); 084 attrs.addCDATAAttribute("metadataPath", metaDef.getId().substring(1)); 085 XMLUtils.startElement(contentHandler, "items", attrs); 086 087 Map<Object, I18nizableText> entries = enumerator.getEntries(); 088 for (Object code : entries.keySet()) 089 { 090 String codeStr = code.toString(); 091 if (StringUtils.isNotEmpty(codeStr)) 092 { 093 I18nizableText value = entries.get(code); 094 095 AttributesImpl valueAttrs = new AttributesImpl(); 096 valueAttrs.addCDATAAttribute("code", codeStr); 097 098 XMLUtils.startElement(contentHandler, "item", valueAttrs); 099 value.toSAX(contentHandler); 100 XMLUtils.endElement(contentHandler, "item"); 101 } 102 } 103 104 XMLUtils.endElement(contentHandler, "items"); 105 } 106 else if (metaDef.getType() == MetadataType.CONTENT) 107 { 108 if (_odfRefTableHelper.isTableReference(metaDef.getContentType())) 109 { 110 _odfRefTableHelper.saxItems(contentHandler, metaDef); 111 } 112 else if (StringUtils.isNotEmpty(metaDef.getContentType())) 113 { 114 _saxContents(metaDef); 115 } 116 } 117 } 118 else 119 { 120 // no metadata definition found or no metadata path has been defined 121 XMLUtils.startElement(contentHandler, "items"); 122 XMLUtils.endElement(contentHandler, "items"); 123 } 124 125 } 126 catch (Exception e) 127 { 128 throw new ProcessingException("Error retrieving the values of metadata '" + metadataPath + "'", e); 129 } 130 131 contentHandler.endDocument(); 132 } 133 134 /** 135 * SAX contents of the type defined by the metadata definition 136 * @param metaDef The metadata definition 137 * @throws SAXException if an error occurred while saxing 138 */ 139 protected void _saxContents(MetadataDefinition metaDef) throws SAXException 140 { 141 AttributesImpl attrs = new AttributesImpl(); 142 attrs.addCDATAAttribute("metadataName", metaDef.getName()); 143 attrs.addCDATAAttribute("metadataPath", metaDef.getId()); 144 attrs.addCDATAAttribute("contentTypeId", metaDef.getContentType()); 145 XMLUtils.startElement(contentHandler, "items", attrs); 146 147 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, metaDef.getContentType()); 148 149 String xpathQuery = ContentQueryHelper.getContentXPathQuery(cTypeExpr); 150 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 151 152 for (Content content : contents) 153 { 154 AttributesImpl valueAttrs = new AttributesImpl(); 155 valueAttrs.addCDATAAttribute("id", content.getId()); 156 XMLUtils.createElement(contentHandler, "item", valueAttrs, content.getTitle()); 157 } 158 159 XMLUtils.endElement(contentHandler, "items"); 160 } 161 162 163 /** 164 * Get a metadata definition from its path. 165 * @param contentType the content type. 166 * @param metadataPath the metadata path. 167 * @return the metadata definition or null if not found. 168 */ 169 protected MetadataDefinition _getMetadataDefinition(ContentType contentType, String metadataPath) 170 { 171 String[] pathSegments = StringUtils.split(metadataPath, '/'); 172 173 if (pathSegments.length == 0) 174 { 175 return null; 176 } 177 178 MetadataDefinition metadataDef = contentType.getMetadataDefinition(pathSegments[0]); 179 180 for (int i = 1; i < pathSegments.length && metadataDef != null; i++) 181 { 182 metadataDef = metadataDef.getMetadataDefinition(pathSegments[i]); 183 } 184 185 return metadataDef; 186 } 187 188}