001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.acacia.client; 029 030import org.opencms.acacia.client.css.I_CmsLayoutBundle; 031import org.opencms.acacia.client.entity.CmsEntityBackend; 032import org.opencms.acacia.shared.CmsContentDefinition; 033import org.opencms.acacia.shared.CmsEntity; 034import org.opencms.acacia.shared.CmsEntityAttribute; 035import org.opencms.acacia.shared.CmsTabInfo; 036import org.opencms.gwt.client.ui.CmsTabbedPanel; 037import org.opencms.gwt.shared.CmsGwtConstants; 038 039import java.util.List; 040 041import com.google.gwt.core.client.JavaScriptObject; 042import com.google.gwt.dom.client.Element; 043import com.google.gwt.json.client.JSONObject; 044import com.google.gwt.json.client.JSONParser; 045import com.google.gwt.user.client.ui.FlowPanel; 046import com.google.gwt.user.client.ui.Panel; 047 048/** 049 * CmsRenderer which delegates the rendering of an entity to native Javascript. 050 * 051 * This renderer will interpret its configuration string as a JSON object (which we will call 'config'). 052 * To render an entity, it will take the name of a function from config.render and then call the function 053 * with the entity to render, the parent element, a VIE wrapper, and the configuration object as parameters. 054 */ 055public class CmsNativeComplexWidgetRenderer implements I_CmsEntityRenderer { 056 057 /** The entity CSS class. */ 058 public static final String ENTITY_CLASS = I_CmsLayoutBundle.INSTANCE.form().entity(); 059 060 /** The attribute label CSS class. */ 061 public static final String LABEL_CLASS = I_CmsLayoutBundle.INSTANCE.form().label(); 062 063 /** The widget holder CSS class. */ 064 public static final String WIDGET_HOLDER_CLASS = I_CmsLayoutBundle.INSTANCE.form().widgetHolder(); 065 066 /** The configuration string. */ 067 private String m_configuration; 068 069 /** The parsed JSON value from the configuration string. */ 070 private JSONObject m_jsonConfig; 071 072 /** The native renderer instance. */ 073 private JavaScriptObject m_nativeInstance; 074 075 /** 076 * Default constructor.<p> 077 */ 078 public CmsNativeComplexWidgetRenderer() { 079 080 } 081 082 /** 083 * Creates a new configured instance.<p> 084 * 085 * @param configuration the configuration string 086 */ 087 public CmsNativeComplexWidgetRenderer(String configuration) { 088 089 m_configuration = configuration; 090 m_jsonConfig = JSONParser.parseLenient(configuration).isObject(); 091 } 092 093 /** 094 * @see org.opencms.acacia.client.I_CmsEntityRenderer#configure(java.lang.String) 095 */ 096 public CmsNativeComplexWidgetRenderer configure(String configuration) { 097 098 return new CmsNativeComplexWidgetRenderer(configuration); 099 } 100 101 /** 102 * @see org.opencms.acacia.client.I_CmsEntityRenderer#getName() 103 */ 104 public String getName() { 105 106 return CmsContentDefinition.NATIVE_RENDERER; 107 } 108 109 /** 110 * @see org.opencms.acacia.client.I_CmsEntityRenderer#renderAttributeValue(org.opencms.acacia.shared.CmsEntity, org.opencms.acacia.client.CmsAttributeHandler, int, com.google.gwt.user.client.ui.Panel) 111 */ 112 public void renderAttributeValue( 113 CmsEntity parentEntity, 114 CmsAttributeHandler attributeHandler, 115 int attributeIndex, 116 Panel context) { 117 118 notSupported(); 119 } 120 121 /** 122 * @see org.opencms.acacia.client.I_CmsEntityRenderer#renderForm(org.opencms.acacia.shared.CmsEntity, java.util.List, com.google.gwt.user.client.ui.Panel, org.opencms.acacia.client.I_CmsAttributeHandler, int) 123 */ 124 public CmsTabbedPanel<FlowPanel> renderForm( 125 CmsEntity entity, 126 List<CmsTabInfo> tabInfos, 127 Panel context, 128 I_CmsAttributeHandler parentHandler, 129 int attributeIndex) { 130 131 throw new UnsupportedOperationException("Custom renderer does not support tabs!"); 132 133 } 134 135 /** 136 * @see org.opencms.acacia.client.I_CmsEntityRenderer#renderForm(org.opencms.acacia.shared.CmsEntity, com.google.gwt.user.client.ui.Panel, org.opencms.acacia.client.I_CmsAttributeHandler, int) 137 */ 138 public void renderForm( 139 final CmsEntity entity, 140 Panel context, 141 final I_CmsAttributeHandler parentHandler, 142 final int attributeIndex) { 143 144 context.addStyleName(ENTITY_CLASS); 145 context.getElement().setAttribute("typeof", entity.getTypeName()); 146 context.getElement().setAttribute(CmsGwtConstants.ATTR_DATA_ID, entity.getId()); 147 String initFunction = CmsContentDefinition.FUNCTION_RENDER_FORM; 148 renderNative( 149 getNativeInstance(), 150 initFunction, 151 context.getElement(), 152 entity, 153 m_jsonConfig.isObject().getJavaScriptObject()); 154 } 155 156 /** 157 * @see org.opencms.acacia.client.I_CmsEntityRenderer#renderInline(org.opencms.acacia.shared.CmsEntity, org.opencms.acacia.client.I_CmsInlineFormParent, org.opencms.acacia.client.I_CmsInlineHtmlUpdateHandler, org.opencms.acacia.client.I_CmsAttributeHandler, int) 158 */ 159 public void renderInline( 160 CmsEntity entity, 161 I_CmsInlineFormParent formParent, 162 I_CmsInlineHtmlUpdateHandler updateHandler, 163 I_CmsAttributeHandler parentHandler, 164 int attributeIndex) { 165 166 notSupported(); 167 } 168 169 /** 170 * @see org.opencms.acacia.client.I_CmsEntityRenderer#renderInline(org.opencms.acacia.shared.CmsEntity, java.lang.String, org.opencms.acacia.client.I_CmsInlineFormParent, org.opencms.acacia.client.I_CmsInlineHtmlUpdateHandler, org.opencms.acacia.client.I_CmsAttributeHandler, int, int, int) 171 */ 172 public void renderInline( 173 CmsEntity parentEntity, 174 String attributeName, 175 I_CmsInlineFormParent formParent, 176 I_CmsInlineHtmlUpdateHandler updateHandler, 177 I_CmsAttributeHandler parentHandler, 178 int attributeIndex, 179 int minOccurrence, 180 int maxOccurrence) { 181 182 CmsEntityAttribute attribute = parentEntity.getAttribute(attributeName); 183 String renderInline = CmsContentDefinition.FUNCTION_RENDER_INLINE; 184 if (attribute != null) { 185 List<CmsEntity> values = attribute.getComplexValues(); 186 List<Element> elements = CmsEntityBackend.getInstance().getAttributeElements( 187 parentEntity, 188 attributeName, 189 formParent.getElement()); 190 for (int i = 0; i < elements.size(); i++) { 191 Element element = elements.get(i); 192 if (i < values.size()) { 193 CmsEntity value = values.get(i); 194 renderNative(getNativeInstance(), renderInline, element, value, m_jsonConfig.getJavaScriptObject()); 195 } 196 } 197 } 198 } 199 200 /** 201 * Creates the native renderer instance.<p> 202 * 203 * @param initCall the name of the native function which creates the native renderer instance 204 * 205 * @return the native renderer instance 206 */ 207 protected native JavaScriptObject createNativeInstance(String initCall) /*-{ 208 if ($wnd[initCall]) { 209 return $wnd[initCall](); 210 } else { 211 throw ("No init function found: " + initCall); 212 } 213 }-*/; 214 215 /** 216 * Gets the native renderer instance.<p> 217 * 218 * @return the native renderer instance 219 */ 220 protected JavaScriptObject getNativeInstance() { 221 222 if (m_nativeInstance == null) { 223 m_nativeInstance = createNativeInstance( 224 m_jsonConfig.get(CmsContentDefinition.PARAM_INIT_CALL).isString().stringValue()); 225 } 226 return m_nativeInstance; 227 } 228 229 /** 230 * Calls the native render function.<p> 231 * 232 * @param nativeRenderer the native renderer instance 233 * @param renderFunction the name of the render function 234 * @param element the element in which to render the entity 235 * @param entity the entity to render 236 * @param config the configuration 237 */ 238 protected native void renderNative( 239 JavaScriptObject nativeRenderer, 240 String renderFunction, 241 com.google.gwt.dom.client.Element element, 242 CmsEntity entity, 243 JavaScriptObject config) /*-{ 244 var entityWrapper = new $wnd.acacia.CmsEntityWrapper(); 245 entityWrapper.setEntity(entity); 246 var backEndWrapper = new $wnd.acacia.CmsEntityBackendWrapper(); 247 if (nativeRenderer && nativeRenderer[renderFunction]) { 248 nativeRenderer[renderFunction](element, entityWrapper, 249 backEndWrapper, config); 250 } else if ($wnd.console) { 251 $wnd.console.log("Rendering function not found: " + renderFunction); 252 } 253 }-*/; 254 255 /** 256 * Throws an error indicating that a method is not supported.<p> 257 */ 258 private void notSupported() { 259 260 throw new UnsupportedOperationException("method not supported by this renderer!"); 261 } 262}