001/* 002 * Copyright 2018 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.io.IOException; 019 020import org.apache.avalon.framework.service.ServiceException; 021import org.apache.avalon.framework.service.ServiceManager; 022import org.apache.avalon.framework.service.Serviceable; 023import org.apache.cocoon.ProcessingException; 024import org.apache.cocoon.environment.ObjectModelHelper; 025import org.apache.cocoon.environment.Request; 026import org.apache.cocoon.generation.AbstractGenerator; 027import org.apache.cocoon.xml.AttributesImpl; 028import org.apache.cocoon.xml.XMLUtils; 029import org.apache.commons.lang3.ArrayUtils; 030import org.apache.commons.lang3.StringUtils; 031import org.xml.sax.SAXException; 032 033import org.ametys.cms.repository.Content; 034import org.ametys.plugins.repository.model.CompositeDefinition; 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.runtime.model.ElementDefinition; 037import org.ametys.runtime.model.ModelItem; 038import org.ametys.runtime.model.ModelViewItem; 039import org.ametys.runtime.model.View; 040import org.ametys.runtime.model.ViewItem; 041import org.ametys.runtime.model.ViewItemAccessor; 042import org.ametys.runtime.model.ViewItemGroup; 043import org.ametys.runtime.util.Labelable; 044 045/** 046 * Generates content type's definition. 047 */ 048public class ContentTypeGenerator extends AbstractGenerator implements Serviceable 049{ 050 private ContentTypesHelper _cTypeHelper; 051 private ContentTypeExtensionPoint _cTypeEP; 052 053 public void service(ServiceManager manager) throws ServiceException 054 { 055 _cTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 056 _cTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 057 } 058 059 public void generate() throws IOException, SAXException, ProcessingException 060 { 061 Request request = ObjectModelHelper.getRequest(objectModel); 062 String cTypeId = parameters.getParameter("contentTypeId", null); 063 Content content = (Content) request.getAttribute(Content.class.getName()); 064 065 if (StringUtils.isBlank(cTypeId) && content == null) 066 { 067 throw new IllegalArgumentException("Missing content in request or content type id parameter. Cannot compute rendering from model."); 068 } 069 070 String viewName = StringUtils.defaultIfBlank(parameters.getParameter("view", ""), "main"); 071 072 contentHandler.startDocument(); 073 if (StringUtils.isNotBlank(cTypeId)) 074 { 075 _saxViewFromContentType(cTypeId, viewName); 076 } 077 else 078 { 079 _saxViewFromContent(content, viewName); 080 } 081 contentHandler.endDocument(); 082 } 083 084 private void _saxViewFromContent(Content content, String viewName) throws SAXException 085 { 086 View view = _cTypeHelper.getView(viewName, content.getTypes(), content.getMixinTypes()); 087 088 AttributesImpl atts = new AttributesImpl(); 089 atts.addCDATAAttribute("id", _cTypeHelper.getContentTypeIdForRendering(content)); 090 atts.addCDATAAttribute("view", viewName); 091 XMLUtils.startElement(contentHandler, "contentType", atts); 092 093 _saxNonNullI18nizableText(_cTypeHelper.getContentTypeLabel(content), "label"); 094 _saxNonNullI18nizableText(_cTypeHelper.getContentTypeDescription(content), "description"); 095 096 _saxViewItemAccessor(view, null); 097 098 XMLUtils.endElement(contentHandler, "contentType"); 099 } 100 101 private void _saxViewFromContentType(String cTypeId, String viewName) throws SAXException 102 { 103 View view = _cTypeHelper.getView(viewName, new String[] {cTypeId}, ArrayUtils.EMPTY_STRING_ARRAY); 104 105 ContentType cType = _cTypeEP.getExtension(cTypeId); 106 AttributesImpl atts = new AttributesImpl(); 107 atts.addCDATAAttribute("id", cTypeId); 108 atts.addCDATAAttribute("view", viewName); 109 XMLUtils.startElement(contentHandler, "contentType", atts); 110 111 _saxNonNullI18nizableText(cType.getLabel(), "label"); 112 _saxNonNullI18nizableText(cType.getDescription(), "description"); 113 114 _saxViewItemAccessor(view, null); 115 116 XMLUtils.endElement(contentHandler, "contentType"); 117 } 118 119 private void _saxViewItemAccessor(ViewItemAccessor viewItemAccessor, String prefix) throws SAXException 120 { 121 for (ViewItem item : viewItemAccessor.getViewItems()) 122 { 123 if (item instanceof ModelViewItem) 124 { 125 _saxModelViewItem((ModelViewItem) item, prefix); 126 } 127 else if (item instanceof ViewItemGroup) 128 { 129 _saxViewItemGroup((ViewItemGroup) item, prefix); 130 } 131 } 132 } 133 134 private void _saxModelViewItem(ModelViewItem modelViewItem, String prefix) throws SAXException 135 { 136 ModelItem modelItem = modelViewItem.getDefinition(); 137 String name = modelItem.getName(); 138 139 AttributesImpl atts = new AttributesImpl(); 140 atts.addCDATAAttribute("name", name); 141 atts.addCDATAAttribute("path", prefix == null ? name : prefix + name); 142 143 if (modelItem instanceof ElementDefinition) 144 { 145 ElementDefinition definition = (ElementDefinition) modelItem; 146 147 atts.addCDATAAttribute("type", definition.getType().getId()); 148 atts.addCDATAAttribute("multiple", String.valueOf(definition.isMultiple())); 149 } 150 else if (modelItem instanceof CompositeDefinition) 151 { 152 atts.addCDATAAttribute("type", "composite"); 153 } 154 else if (modelItem instanceof org.ametys.plugins.repository.model.RepeaterDefinition) 155 { 156 atts.addCDATAAttribute("type", "repeater"); 157 } 158 159 XMLUtils.startElement(contentHandler, "metadata", atts); 160 161 _saxNonNullI18nizableText(modelViewItem.getLabel(), "label"); 162 _saxNonNullI18nizableText(modelViewItem.getDescription(), "description"); 163 164 if (modelViewItem instanceof ViewItemAccessor) 165 { 166 _saxViewItemAccessor((ViewItemAccessor) modelViewItem, prefix == null ? name + "/" : prefix + name + "/"); 167 } 168 169 XMLUtils.endElement(contentHandler, "metadata"); 170 } 171 172 private void _saxViewItemGroup(ViewItemGroup group, String prefix) throws SAXException 173 { 174 AttributesImpl atts = new AttributesImpl(); 175 176 if (group.getRole() != null) 177 { 178 atts.addCDATAAttribute("role", group.getRole()); 179 } 180 if (group.getName() != null) 181 { 182 atts.addCDATAAttribute("name", group.getName()); 183 } 184 185 XMLUtils.startElement(contentHandler, "fieldset", atts); 186 187 _saxNonNullI18nizableText(((Labelable) group).getLabel(), "label"); 188 189 _saxViewItemAccessor(group, prefix); 190 191 XMLUtils.endElement(contentHandler, "fieldset"); 192 } 193 194 private void _saxNonNullI18nizableText(I18nizableText text, String tagName) throws SAXException 195 { 196 if (text != null) 197 { 198 text.toSAX(contentHandler, tagName); 199 } 200 } 201}