1 31 32 package org.opencms.xml.page; 33 34 import org.opencms.configuration.CmsConfigurationManager; 35 import org.opencms.file.CmsFile; 36 import org.opencms.file.CmsObject; 37 import org.opencms.file.CmsResource; 38 import org.opencms.i18n.CmsEncoder; 39 import org.opencms.i18n.CmsLocaleManager; 40 import org.opencms.main.CmsIllegalArgumentException; 41 import org.opencms.main.CmsLog; 42 import org.opencms.main.CmsRuntimeException; 43 import org.opencms.staticexport.CmsLinkProcessor; 44 import org.opencms.staticexport.CmsLinkTable; 45 import org.opencms.xml.A_CmsXmlDocument; 46 import org.opencms.xml.CmsXmlContentDefinition; 47 import org.opencms.xml.CmsXmlEntityResolver; 48 import org.opencms.xml.CmsXmlException; 49 import org.opencms.xml.CmsXmlUtils; 50 import org.opencms.xml.content.CmsXmlContentErrorHandler; 51 import org.opencms.xml.types.CmsXmlHtmlValue; 52 import org.opencms.xml.types.I_CmsXmlContentValue; 53 import org.opencms.xml.types.I_CmsXmlSchemaType; 54 55 import java.util.ArrayList ; 56 import java.util.Collections ; 57 import java.util.HashMap ; 58 import java.util.HashSet ; 59 import java.util.Iterator ; 60 import java.util.List ; 61 import java.util.Locale ; 62 import java.util.Map ; 63 import java.util.Set ; 64 65 import org.apache.commons.logging.Log; 66 67 import org.dom4j.Attribute; 68 import org.dom4j.Document; 69 import org.dom4j.DocumentHelper; 70 import org.dom4j.Element; 71 import org.xml.sax.InputSource ; 72 73 89 public class CmsXmlPage extends A_CmsXmlDocument { 90 91 92 public static final String ATTRIBUTE_ENABLED = "enabled"; 93 94 95 public static final String ATTRIBUTE_INTERNAL = "internal"; 96 97 98 public static final String ATTRIBUTE_LANGUAGE = "language"; 99 100 101 public static final String ATTRIBUTE_NAME = "name"; 102 103 104 public static final String ATTRIBUTE_TYPE = "type"; 105 106 107 public static final String NODE_ANCHOR = "anchor"; 108 109 110 public static final String NODE_CONTENT = "content"; 111 112 113 public static final String NODE_ELEMENTS = "elements"; 114 115 116 public static final String NODE_LINK = "link"; 117 118 119 public static final String NODE_LINKS = "links"; 120 121 122 public static final String NODE_PAGE = "page"; 123 124 125 public static final String NODE_PAGES = "pages"; 126 127 128 public static final String NODE_QUERY = "query"; 129 130 131 public static final String NODE_TARGET = "target"; 132 133 134 public static final String PROPERTY_ALLOW_RELATIVE = "allowRelativeLinks"; 135 136 137 public static final String XMLPAGE_XSD_SYSTEM_ID = CmsConfigurationManager.DEFAULT_DTD_PREFIX + "xmlpage.xsd"; 138 139 140 private static final Log LOG = CmsLog.getLog(CmsXmlPage.class); 141 142 143 private static CmsXmlContentDefinition m_xmlPageContentDefinition; 144 145 146 private static final String NODE_ELEMENT = "element"; 147 148 149 private boolean m_allowRelativeLinks; 150 151 159 public CmsXmlPage(Document document, String encoding) { 160 161 initDocument(document, encoding, getContentDefinition()); 162 } 163 164 174 public CmsXmlPage(Locale locale, String encoding) { 175 176 initDocument(CmsXmlPageFactory.createDocument(locale), encoding, getContentDefinition()); 177 } 178 179 182 public void addLocale(CmsObject cms, Locale locale) throws CmsXmlException { 183 184 if (hasLocale(locale)) { 185 throw new CmsXmlException(Messages.get().container(Messages.ERR_XML_PAGE_LOCALE_EXISTS_1, locale)); 186 } 187 getContentDefinition().createLocale(cms, this, m_document.getRootElement(), locale); 189 initDocument(m_document, m_encoding, getContentDefinition()); 191 } 192 193 204 public void addValue(String name, Locale locale) throws CmsIllegalArgumentException { 205 206 if (name.indexOf('[') >= 0) { 207 throw new CmsIllegalArgumentException( 208 Messages.get().container(Messages.ERR_XML_PAGE_CONTAINS_INDEX_1, name)); 209 } 210 211 if (hasValue(name, locale)) { 212 throw new CmsIllegalArgumentException(Messages.get().container( 213 Messages.ERR_XML_PAGE_LANG_ELEM_EXISTS_2, 214 name, 215 locale)); 216 } 217 218 Element pages = m_document.getRootElement(); 219 String localeStr = locale.toString(); 220 Element page = null; 221 222 for (Iterator i = pages.elementIterator(NODE_PAGE); i.hasNext();) { 224 Element nextPage = (Element)i.next(); 225 String language = nextPage.attributeValue(ATTRIBUTE_LANGUAGE); 226 if (localeStr.equals(language)) { 227 page = nextPage; 229 break; 230 } 231 } 232 233 Element element; 235 if (page != null) { 236 element = page.addElement(NODE_ELEMENT).addAttribute(ATTRIBUTE_NAME, name); 238 } else { 239 element = pages.addElement(NODE_PAGE).addAttribute(ATTRIBUTE_LANGUAGE, localeStr); 241 element = element.addElement(NODE_ELEMENT).addAttribute(ATTRIBUTE_NAME, name); 242 } 243 244 element.addElement(NODE_LINKS); 246 element.addElement(NODE_CONTENT); 247 248 CmsXmlHtmlValue value = new CmsXmlHtmlValue(this, element, locale); 249 250 addBookmark(CmsXmlUtils.createXpathElement(name, 1), locale, true, value); 252 } 253 254 259 public boolean getAllowRelativeLinks() { 260 261 return m_allowRelativeLinks; 262 } 263 264 267 public CmsXmlContentDefinition getContentDefinition() throws CmsRuntimeException { 268 269 if (m_xmlPageContentDefinition == null) { 270 CmsXmlEntityResolver resolver = new CmsXmlEntityResolver(null); 272 InputSource source; 273 try { 274 source = resolver.resolveEntity(null, XMLPAGE_XSD_SYSTEM_ID); 275 m_xmlPageContentDefinition = CmsXmlContentDefinition.unmarshal(source, XMLPAGE_XSD_SYSTEM_ID, resolver); 277 } catch (CmsXmlException e) { 278 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_XML_PAGE_UNMARSHAL_CONTENDDEF_0), e); 279 } 280 } 281 return m_xmlPageContentDefinition; 282 } 283 284 287 public CmsLinkProcessor getLinkProcessor(CmsObject cms, CmsLinkTable linkTable) { 288 289 String relativeRoot = null; 291 if ((!m_allowRelativeLinks) && (m_file != null)) { 292 relativeRoot = CmsResource.getParentFolder(cms.getSitePath(m_file)); 293 } 294 return new CmsLinkProcessor(cms, linkTable, getEncoding(), relativeRoot); 295 } 296 297 304 public CmsLinkTable getLinkTable(String name, Locale locale) { 305 306 CmsXmlHtmlValue value = (CmsXmlHtmlValue)getValue(name, locale); 307 if (value != null) { 308 return value.getLinkTable(); 309 } 310 return new CmsLinkTable(); 311 } 312 313 316 public List getNames(Locale locale) { 317 318 Object o = m_elementNames.get(locale); 319 if (o != null) { 320 List result = new ArrayList (8); 321 Iterator i = ((Set )o).iterator(); 322 while (i.hasNext()) { 323 String path = (String )i.next(); 324 result.add(CmsXmlUtils.removeXpathIndex(path)); 325 } 326 return result; 327 } 328 return Collections.EMPTY_LIST; 329 } 330 331 338 public boolean isEnabled(String name, Locale locale) { 339 340 CmsXmlHtmlValue value = (CmsXmlHtmlValue)getValue(name, locale); 341 342 if (value != null) { 343 Element element = value.getElement(); 344 Attribute enabled = element.attribute(ATTRIBUTE_ENABLED); 345 return (enabled == null || Boolean.valueOf(enabled.getValue()).booleanValue()); 346 } 347 348 return false; 349 } 350 351 358 public void removeValue(String name, Locale locale) { 359 360 I_CmsXmlContentValue value = removeBookmark(CmsXmlUtils.createXpath(name, 1), locale); 361 if (value != null) { 362 Element element = value.getElement(); 363 element.detach(); 364 } 365 } 366 367 378 public void renameValue(String oldValue, String newValue, Locale locale) throws CmsIllegalArgumentException { 379 380 CmsXmlHtmlValue oldXmlHtmlValue = (CmsXmlHtmlValue)getValue(oldValue, locale); 381 if (oldXmlHtmlValue == null) { 382 throw new CmsIllegalArgumentException(Messages.get().container( 383 Messages.ERR_XML_PAGE_NO_ELEM_FOR_LANG_2, 384 oldValue, 385 locale)); 386 } 387 388 if (hasValue(newValue, locale)) { 389 throw new CmsIllegalArgumentException(Messages.get().container( 390 Messages.ERR_XML_PAGE_LANG_ELEM_EXISTS_2, 391 newValue, 392 locale)); 393 } 394 if (newValue.indexOf('[') >= 0) { 395 throw new CmsIllegalArgumentException(Messages.get().container( 396 Messages.ERR_XML_PAGE_CONTAINS_INDEX_1, 397 newValue)); 398 } 399 400 Element element = oldXmlHtmlValue.getElement(); 402 403 element.addAttribute(ATTRIBUTE_NAME, newValue); 405 406 initDocument(m_document, m_encoding, getContentDefinition()); 408 } 409 410 420 public void setEnabled(String name, Locale locale, boolean isEnabled) { 421 422 CmsXmlHtmlValue value = (CmsXmlHtmlValue)getValue(name, locale); 423 Element element = value.getElement(); 424 Attribute enabled = element.attribute(ATTRIBUTE_ENABLED); 425 426 if (enabled == null) { 427 if (!isEnabled) { 428 element.addAttribute(ATTRIBUTE_ENABLED, Boolean.toString(isEnabled)); 429 } 430 } else if (isEnabled) { 431 element.remove(enabled); 432 } else { 433 enabled.setValue(Boolean.toString(isEnabled)); 434 } 435 } 436 437 451 public void setStringValue(CmsObject cms, String name, Locale locale, String content) throws CmsXmlException { 452 453 CmsXmlHtmlValue value = (CmsXmlHtmlValue)getValue(name, locale); 454 455 if (value != null) { 456 value.setStringValue(cms, content); 458 } else { 459 throw new CmsXmlException(Messages.get().container( 460 Messages.ERR_XML_PAGE_INVALID_ELEM_SELECT_2, 461 locale, 462 name)); 463 } 464 } 465 466 469 public CmsXmlContentErrorHandler validate(CmsObject cms) { 470 471 return new CmsXmlContentErrorHandler(); 473 } 474 475 478 protected void initDocument(Document document, String encoding, CmsXmlContentDefinition definition) { 479 480 m_encoding = CmsEncoder.lookupEncoding(encoding, encoding); 481 m_document = document; 482 m_elementLocales = new HashMap (); 483 m_elementNames = new HashMap (); 484 m_locales = new HashSet (); 485 486 if (!NODE_PAGES.equals(m_document.getRootElement().getName())) { 488 convertOldDocument(); 489 } 490 491 clearBookmarks(); 493 Element pages = m_document.getRootElement(); 494 try { 495 for (Iterator i = pages.elementIterator(NODE_PAGE); i.hasNext();) { 496 497 Element page = (Element)i.next(); 498 Locale locale = CmsLocaleManager.getLocale(page.attributeValue(ATTRIBUTE_LANGUAGE)); 499 for (Iterator j = page.elementIterator(NODE_ELEMENT); j.hasNext();) { 500 501 Element element = (Element)j.next(); 502 String name = element.attributeValue(ATTRIBUTE_NAME); 503 504 String elementEnabled = element.attributeValue(ATTRIBUTE_ENABLED); 505 boolean enabled = (elementEnabled == null) ? true : Boolean.valueOf(elementEnabled).booleanValue(); 506 507 CmsXmlHtmlValue value = new CmsXmlHtmlValue(this, element, locale); 509 value.setContentDefinition(definition); 510 511 addBookmark(CmsXmlUtils.createXpathElement(name, 1), locale, enabled, value); 513 } 514 addLocale(locale); 515 } 516 } catch (NullPointerException e) { 517 LOG.error(Messages.get().getBundle().key(Messages.ERR_XML_PAGE_INIT_BOOKMARKS_0), e); 518 } 519 } 520 521 526 protected void setAllowRelativeLinks(boolean value) { 527 528 m_allowRelativeLinks = value; 529 } 530 531 536 protected void setFile(CmsFile file) { 537 538 m_file = file; 539 } 540 541 545 private void convertOldDocument() { 546 547 Document newDocument = DocumentHelper.createDocument(); 548 Element root = newDocument.addElement(NODE_PAGES); 549 root.add(I_CmsXmlSchemaType.XSI_NAMESPACE); 550 root.addAttribute(I_CmsXmlSchemaType.XSI_NAMESPACE_ATTRIBUTE_NO_SCHEMA_LOCATION, XMLPAGE_XSD_SYSTEM_ID); 551 552 Map pages = new HashMap (); 553 554 for (Iterator i = m_document.getRootElement().element(NODE_ELEMENTS).elementIterator(NODE_ELEMENT); i.hasNext();) { 555 556 Element elem = (Element)i.next(); 557 try { 558 String elementName = elem.attributeValue(ATTRIBUTE_NAME); 559 String elementLang = elem.attributeValue(ATTRIBUTE_LANGUAGE); 560 String elementEnabled = elem.attributeValue(ATTRIBUTE_ENABLED); 561 boolean enabled = (elementEnabled == null) ? true : Boolean.valueOf(elementEnabled).booleanValue(); 562 563 Element page = (Element)pages.get(elementLang); 564 if (page == null) { 565 page = root.addElement(NODE_PAGE).addAttribute(ATTRIBUTE_LANGUAGE, elementLang); 567 pages.put(elementLang, page); 568 } 569 570 Element newElement = page.addElement(NODE_ELEMENT).addAttribute(ATTRIBUTE_NAME, elementName); 571 if (!enabled) { 572 newElement.addAttribute(ATTRIBUTE_ENABLED, String.valueOf(enabled)); 573 } 574 Element links = elem.element(NODE_LINKS); 575 if (links != null) { 576 newElement.add(links.createCopy()); 577 } 578 Element content = elem.element(NODE_CONTENT); 579 if (content != null) { 580 newElement.add(content.createCopy()); 581 } 582 583 } catch (NullPointerException e) { 584 LOG.error(Messages.get().getBundle().key(Messages.ERR_XML_PAGE_CONVERT_CONTENT_0), e); 585 } 586 } 587 588 m_document = newDocument; 590 } 591 } | Popular Tags |