1 31 32 package org.opencms.xml; 33 34 import org.opencms.file.CmsObject; 35 import org.opencms.i18n.CmsEncoder; 36 import org.opencms.main.CmsLog; 37 import org.opencms.main.CmsRuntimeException; 38 import org.opencms.main.OpenCms; 39 import org.opencms.security.CmsRole; 40 import org.opencms.security.CmsRoleViolationException; 41 import org.opencms.util.CmsStringUtil; 42 import org.opencms.widgets.I_CmsWidget; 43 import org.opencms.xml.content.I_CmsXmlContentHandler; 44 import org.opencms.xml.types.CmsXmlNestedContentDefinition; 45 import org.opencms.xml.types.I_CmsXmlSchemaType; 46 47 import java.io.UnsupportedEncodingException ; 48 import java.util.ArrayList ; 49 import java.util.Collections ; 50 import java.util.HashMap ; 51 import java.util.Iterator ; 52 import java.util.List ; 53 import java.util.Map ; 54 import java.util.Set ; 55 56 import org.apache.commons.collections.FastHashMap; 57 import org.apache.commons.logging.Log; 58 59 import org.dom4j.Document; 60 import org.dom4j.Element; 61 62 71 public class CmsXmlContentTypeManager { 72 73 74 private static final Log LOG = CmsLog.getLog(CmsXmlContentTypeManager.class); 75 76 77 private Map m_contentHandlers; 78 79 80 private Map m_defaultWidgets; 81 82 83 private Map m_registeredTypes; 84 85 86 private Map m_registeredWidgets; 87 88 89 private Map m_widgetAliases; 90 91 94 public CmsXmlContentTypeManager() { 95 96 98 m_registeredTypes = new HashMap (); 99 m_defaultWidgets = new HashMap (); 100 m_registeredWidgets = new HashMap (); 101 m_widgetAliases = new HashMap (); 102 103 FastHashMap fastMap = new FastHashMap(); 104 fastMap.setFast(true); 105 m_contentHandlers = fastMap; 106 107 if (CmsLog.INIT.isInfoEnabled()) { 108 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_START_CONTENT_CONFIG_0)); 109 } 110 } 111 112 117 public static CmsXmlContentTypeManager createTypeManagerForTestCases() { 118 119 CmsXmlContentTypeManager typeManager = new CmsXmlContentTypeManager(); 120 121 typeManager.addWidget("org.opencms.widgets.CmsCalendarWidget", null); 122 typeManager.addWidget("org.opencms.widgets.CmsHtmlWidget", null); 123 typeManager.addWidget("org.opencms.widgets.CmsInputWidget", null); 124 125 typeManager.addSchemaType("org.opencms.xml.types.CmsXmlDateTimeValue", "org.opencms.widgets.CmsCalendarWidget"); 126 typeManager.addSchemaType("org.opencms.xml.types.CmsXmlHtmlValue", "org.opencms.widgets.CmsHtmlWidget"); 127 typeManager.addSchemaType("org.opencms.xml.types.CmsXmlLocaleValue", "org.opencms.widgets.CmsInputWidget"); 128 typeManager.addSchemaType("org.opencms.xml.types.CmsXmlStringValue", "org.opencms.widgets.CmsInputWidget"); 129 130 try { 131 typeManager.initialize(null); 132 } catch (CmsRoleViolationException e) { 133 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_INIT_TYPE_MANAGER_0)); 135 } 136 return typeManager; 137 } 138 139 148 public I_CmsXmlSchemaType addContentType(Class clazz) throws CmsXmlException { 149 150 I_CmsXmlSchemaType type; 151 try { 152 type = (I_CmsXmlSchemaType)clazz.newInstance(); 153 } catch (InstantiationException e) { 154 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_XCC_TYPE_REGISTERED_0)); 155 } catch (IllegalAccessException e) { 156 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_XCC_TYPE_REGISTERED_0)); 157 } catch (ClassCastException e) { 158 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_XCC_TYPE_REGISTERED_0)); 159 } 160 m_registeredTypes.put(type.getTypeName(), type); 161 return type; 162 } 163 164 170 public void addSchemaType(String className, String defaultWidget) { 171 172 Class classClazz; 173 try { 175 classClazz = Class.forName(className); 176 } catch (ClassNotFoundException e) { 177 LOG.error( 178 Messages.get().getBundle().key(Messages.LOG_XML_CONTENT_SCHEMA_TYPE_CLASS_NOT_FOUND_1, className), 179 e); 180 return; 181 } 182 183 I_CmsXmlSchemaType type; 185 try { 186 type = addContentType(classClazz); 187 } catch (Exception e) { 188 LOG.error(Messages.get().getBundle().key( 189 Messages.LOG_INIT_XML_CONTENT_SCHEMA_TYPE_CLASS_ERROR_1, 190 classClazz.getName()), e); 191 return; 192 } 193 194 I_CmsWidget widget = getWidget(defaultWidget); 196 if (widget == null) { 197 LOG.error(Messages.get().getBundle().key( 198 Messages.LOG_INIT_DEFAULT_WIDGET_FOR_CONTENT_TYPE_2, 199 defaultWidget, 200 type.getTypeName())); 201 return; 202 } 203 204 m_defaultWidgets.put(type.getTypeName(), widget); 206 207 if (CmsLog.INIT.isInfoEnabled()) { 208 CmsLog.INIT.info(Messages.get().getBundle().key( 209 Messages.INIT_ADD_ST_USING_WIDGET_2, 210 type.getTypeName(), 211 widget.getClass().getName())); 212 } 213 } 214 215 221 public void addWidget(String className, String aliasName) { 222 223 Class widgetClazz; 224 I_CmsWidget widget; 225 try { 226 widgetClazz = Class.forName(className); 227 widget = (I_CmsWidget)widgetClazz.newInstance(); 228 } catch (Exception e) { 229 LOG.error(Messages.get().getBundle().key(Messages.LOG_XML_WIDGET_INITIALIZING_ERROR_1, className), e); 230 return; 231 } 232 233 m_registeredWidgets.put(widgetClazz.getName(), widget); 234 235 if (aliasName != null) { 236 m_widgetAliases.put(aliasName, widgetClazz.getName()); 237 } 238 239 if (CmsLog.INIT.isInfoEnabled()) { 240 if (aliasName != null) { 241 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_ADD_WIDGET_1, widgetClazz.getName())); 242 } else { 243 CmsLog.INIT.info(Messages.get().getBundle().key( 244 Messages.INIT_ADD_WIDGET_ALIAS_2, 245 widgetClazz.getName(), 246 aliasName)); 247 } 248 } 249 } 250 251 264 public I_CmsXmlContentHandler getContentHandler(String className, String schemaLocation) throws CmsXmlException { 265 266 StringBuffer buffer = new StringBuffer (128); 268 buffer.append(schemaLocation); 269 buffer.append('#'); 270 buffer.append(className); 271 String key = buffer.toString(); 272 273 I_CmsXmlContentHandler contentHandler = (I_CmsXmlContentHandler)m_contentHandlers.get(key); 275 if (contentHandler != null) { 276 return contentHandler; 277 } 278 279 try { 281 contentHandler = (I_CmsXmlContentHandler)Class.forName(className).newInstance(); 282 } catch (InstantiationException e) { 283 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CONTENT_HANDLER_1, key)); 284 } catch (IllegalAccessException e) { 285 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CONTENT_HANDLER_1, key)); 286 } catch (ClassCastException e) { 287 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CONTENT_HANDLER_1, key)); 288 } catch (ClassNotFoundException e) { 289 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CONTENT_HANDLER_1, key)); 290 } 291 292 m_contentHandlers.put(key, contentHandler); 294 return contentHandler; 295 } 296 297 307 public I_CmsXmlSchemaType getContentType(Element typeElement, Set nestedDefinitions) throws CmsXmlException { 308 309 if (!CmsXmlContentDefinition.XSD_NODE_ELEMENT.equals(typeElement.getQName())) { 310 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CD_SCHEMA_STRUCTURE_0)); 311 } 312 if (typeElement.elements().size() > 0) { 313 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CD_SCHEMA_STRUCTURE_0)); 314 } 315 316 int todo = 0; 317 319 String elementName = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_NAME); 320 String typeName = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_TYPE); 321 String defaultValue = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_DEFAULT); 322 String maxOccrs = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_MAX_OCCURS); 323 String minOccrs = typeElement.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_MIN_OCCURS); 324 325 if (CmsStringUtil.isEmpty(elementName) || CmsStringUtil.isEmpty(typeName)) { 326 throw new CmsXmlException(Messages.get().container(Messages.ERR_INVALID_CD_SCHEMA_STRUCTURE_0)); 327 } 328 329 boolean simpleType = true; 330 I_CmsXmlSchemaType schemaType = (I_CmsXmlSchemaType)m_registeredTypes.get(typeName); 331 if (schemaType == null) { 332 333 Iterator i = nestedDefinitions.iterator(); 335 while (i.hasNext()) { 336 337 CmsXmlContentDefinition cd = (CmsXmlContentDefinition)i.next(); 338 if (typeName.equals(cd.getTypeName())) { 339 340 simpleType = false; 341 return new CmsXmlNestedContentDefinition(cd, elementName, minOccrs, maxOccrs); 342 } 343 } 344 345 if (simpleType) { 346 throw new CmsXmlException(Messages.get().container(Messages.ERR_UNKNOWN_SCHEMA_1, typeName)); 347 } 348 } 349 350 if (simpleType) { 351 schemaType = schemaType.newInstance(elementName, minOccrs, maxOccrs); 352 353 if (CmsStringUtil.isNotEmpty(defaultValue)) { 354 schemaType.setDefault(defaultValue); 355 } 356 } 357 358 return schemaType; 359 } 360 361 367 public I_CmsXmlSchemaType getContentType(String typeName) { 368 369 return (I_CmsXmlSchemaType)m_registeredTypes.get(typeName); 370 } 371 372 377 public List getRegisteredSchemaTypes() { 378 379 List result = new ArrayList (m_registeredTypes.values()); 380 Collections.sort(result); 381 return result; 382 } 383 384 392 public String getRegisteredWidgetAlias(String className) { 393 394 Iterator i = m_widgetAliases.keySet().iterator(); 397 while (i.hasNext()) { 398 String aliasName = (String )i.next(); 399 String clazzName = (String )m_widgetAliases.get(aliasName); 400 if (clazzName.equals(className)) { 401 return aliasName; 403 } 404 } 405 return null; 406 } 407 408 413 public List getRegisteredWidgetNames() { 414 415 List result = new ArrayList (m_registeredWidgets.keySet()); 416 Collections.sort(result); 417 return result; 418 } 419 420 426 public I_CmsWidget getWidget(String name) { 427 428 I_CmsWidget result = (I_CmsWidget)m_registeredWidgets.get(name); 430 if (result == null) { 431 String className = (String )m_widgetAliases.get(name); 433 if (className != null) { 434 result = (I_CmsWidget)m_registeredWidgets.get(className); 435 } 436 } 437 if (result != null) { 438 result = result.newInstance(); 439 } 440 return result; 441 } 442 443 449 public I_CmsWidget getWidgetDefault(String typeName) { 450 451 I_CmsWidget result = (I_CmsWidget)m_defaultWidgets.get(typeName); 452 if (result != null) { 453 result = result.newInstance(); 454 } 455 return result; 456 } 457 458 465 public synchronized void initialize(CmsObject cms) throws CmsRoleViolationException { 466 467 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { 468 469 cms.checkRole(CmsRole.ADMINISTRATOR); 471 } 472 473 CmsXmlEntityResolver.initialize(cms, getSchemaBytes()); 475 476 if (CmsLog.INIT.isInfoEnabled()) { 477 CmsLog.INIT.info(Messages.get().getBundle().key( 478 Messages.INIT_NUM_ST_INITIALIZED_1, 479 new Integer (m_registeredTypes.size()))); 480 } 481 } 482 483 488 private byte[] getSchemaBytes() { 489 490 StringBuffer schema = new StringBuffer (512); 491 schema.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 492 schema.append("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\">"); 493 Iterator i = m_registeredTypes.values().iterator(); 494 while (i.hasNext()) { 495 I_CmsXmlSchemaType type = (I_CmsXmlSchemaType)i.next(); 496 schema.append(type.getSchemaDefinition()); 497 } 498 schema.append("</xsd:schema>"); 499 String schemaStr = schema.toString(); 500 501 try { 502 Document doc = CmsXmlUtils.unmarshalHelper(schemaStr, null); 506 schemaStr = CmsXmlUtils.marshal(doc, CmsEncoder.ENCODING_UTF_8); 507 } catch (CmsXmlException e) { 508 LOG.error(Messages.get().getBundle().key(Messages.LOG_PRETTY_PRINT_SCHEMA_BYTES_ERROR_0), e); 510 } 511 if (LOG.isInfoEnabled()) { 512 LOG.info(Messages.get().getBundle().key( 513 Messages.LOG_XML_TYPE_DEFINITION_XSD_2, 514 CmsXmlContentDefinition.XSD_INCLUDE_OPENCMS, 515 schemaStr)); 516 } 517 try { 518 return schemaStr.getBytes(CmsEncoder.ENCODING_UTF_8); 519 } catch (UnsupportedEncodingException e) { 520 LOG.error(Messages.get().getBundle().key(Messages.LOG_CONVERTING_SCHEMA_BYTES_ERROR_0), e); 522 } 523 return null; 524 } 525 } | Popular Tags |