001/* 002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others. 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 * 016 * Contributors: 017 * Thierry Delprat 018 */ 019package org.nuxeo.template.processors; 020 021import java.io.IOException; 022import java.io.Serializable; 023import java.util.Collections; 024import java.util.Date; 025import java.util.List; 026import java.util.Map; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.nuxeo.ecm.core.api.Blob; 031import org.nuxeo.ecm.core.api.PropertyException; 032import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 033import org.nuxeo.ecm.core.api.model.Property; 034import org.nuxeo.ecm.core.convert.api.ConversionService; 035import org.nuxeo.ecm.core.schema.types.Type; 036import org.nuxeo.ecm.core.schema.types.primitives.BooleanType; 037import org.nuxeo.ecm.core.schema.types.primitives.DateType; 038import org.nuxeo.ecm.core.schema.types.primitives.StringType; 039import org.nuxeo.ecm.platform.rendering.fm.adapters.DocumentObjectWrapper; 040import org.nuxeo.runtime.api.Framework; 041import org.nuxeo.template.api.ContentInputType; 042import org.nuxeo.template.api.InputType; 043import org.nuxeo.template.api.TemplateInput; 044import org.nuxeo.template.api.adapters.TemplateBasedDocument; 045 046import freemarker.template.TemplateModelException; 047 048public abstract class AbstractBindingResolver implements InputBindingResolver { 049 050 protected Log log = LogFactory.getLog(AbstractBindingResolver.class); 051 052 protected abstract Object handleLoop(String paramName, Object value); 053 054 protected abstract Object handlePictureField(String paramName, Blob blobValue); 055 056 protected abstract void handleBlobField(String paramName, Blob blobValue); 057 058 protected String handleHtmlField(String paramName, String htmlValue) { 059 return HtmlBodyExtractor.extractHtmlBody(htmlValue); 060 } 061 062 protected DocumentObjectWrapper nuxeoWrapper = new DocumentObjectWrapper(null); 063 064 public AbstractBindingResolver() { 065 super(); 066 } 067 068 protected DocumentObjectWrapper getWrapper() { 069 return nuxeoWrapper; 070 } 071 072 @Override 073 public void resolve(List<TemplateInput> inputParams, Map<String, Object> context, 074 TemplateBasedDocument templateBasedDocument) { 075 076 for (TemplateInput param : inputParams) { 077 try { 078 if (param.isSourceValue()) { 079 if (param.getType() == InputType.Content) { 080 if (ContentInputType.HtmlPreview.getValue().equals(param.getSource())) { 081 BlobHolder bh = templateBasedDocument.getAdaptedDoc().getAdapter(BlobHolder.class); 082 String htmlValue = handleHtmlField(param.getName(), getHtmlValue(bh)); 083 context.put(param.getName(), htmlValue); 084 continue; 085 } else if (ContentInputType.BlobContent.getValue().equals(param.getSource())) { 086 Object propValue = templateBasedDocument.getAdaptedDoc().getPropertyValue(param.getSource()); 087 if (propValue != null && propValue instanceof Blob) { 088 Blob blobValue = (Blob) propValue; 089 context.put(param.getName(), blobValue.getString()); 090 handleBlobField(param.getName(), blobValue); 091 } 092 } else { 093 Object propValue = templateBasedDocument.getAdaptedDoc().getPropertyValue(param.getSource()); 094 if (propValue instanceof String) { 095 String stringContent = (String) propValue; 096 String htmlValue = handleHtmlField(param.getName(), stringContent); 097 context.put(param.getName(), htmlValue); 098 } 099 } 100 } 101 Property property = null; 102 try { 103 property = templateBasedDocument.getAdaptedDoc().getProperty(param.getSource()); 104 } catch (PropertyException e) { 105 log.warn("Unable to ready property " + param.getSource(), e); 106 } 107 108 Serializable value = null; 109 if (property != null) { 110 value = property.getValue(); 111 } 112 113 if (value != null) { 114 if (param.getType() != InputType.Content) { 115 if (Blob.class.isAssignableFrom(value.getClass())) { 116 Blob blob = (Blob) value; 117 if (param.getType() == InputType.PictureProperty) { 118 if (blob.getMimeType() == null || "".equals(blob.getMimeType().trim())) { 119 blob.setMimeType("image/jpeg"); 120 } 121 context.put(param.getName(), handlePictureField(param.getName(), blob)); 122 } 123 } else { 124 if (param.isAutoLoop()) { 125 // should do the same on all children 126 // properties ? 127 Object loopVal = handleLoop(param.getName(), property); 128 context.put(param.getName(), loopVal); 129 } else { 130 context.put(param.getName(), nuxeoWrapper.wrap(property)); 131 } 132 } 133 } 134 } else { 135 // no available value, try to find a default one ... 136 if (property != null) { 137 Type pType = property.getType(); 138 if (pType.getName().equals(BooleanType.ID)) { 139 context.put(param.getName(), new Boolean(false)); 140 } else if (pType.getName().equals(DateType.ID)) { 141 context.put(param.getName(), new Date()); 142 } else if (pType.getName().equals(StringType.ID)) { 143 context.put(param.getName(), ""); 144 } else if (pType.getName().equals(InputType.Content)) { 145 context.put(param.getName(), ""); 146 } else { 147 context.put(param.getName(), "!NOVALUE!"); 148 } 149 // handle special case for pictures 150 if (param.getType() == InputType.PictureProperty) { 151 context.put(param.getName(), handlePictureField(param.getName(), null)); 152 } 153 } else { 154 if (param.getType().equals(InputType.PictureProperty)) { 155 context.put(param.getName(), handlePictureField(param.getName(), null)); 156 } 157 } 158 } 159 160 } else { 161 if (InputType.StringValue.equals(param.getType())) { 162 context.put(param.getName(), param.getStringValue()); 163 } else if (InputType.BooleanValue.equals(param.getType())) { 164 context.put(param.getName(), param.getBooleanValue()); 165 } else if (InputType.DateValue.equals(param.getType())) { 166 context.put(param.getName(), param.getDateValue()); 167 } 168 } 169 } catch (TemplateModelException | IOException e) { 170 log.warn("Unable to handle binding for param " + param.getName(), e); 171 } 172 } 173 } 174 175 protected String getHtmlValue(BlobHolder bh) throws IOException { 176 if (bh == null) { 177 return ""; 178 } 179 180 Blob blob = bh.getBlob(); 181 if (blob != null && "text/html".equals(blob.getMimeType())) { 182 return blob.getString(); 183 } 184 185 ConversionService conversion = Framework.getService(ConversionService.class); 186 BlobHolder htmlBh = conversion.convertToMimeType("text/html", bh, Collections.emptyMap()); 187 if (htmlBh != null) { 188 return htmlBh.getBlob().getString(); 189 } 190 191 if (blob != null && blob.getMimeType() != null && blob.getMimeType().startsWith("text/")) { 192 return blob.getString(); 193 } 194 195 return ""; 196 } 197 198}