1 31 32 package org.opencms.xml; 33 34 import org.opencms.file.CmsFile; 35 import org.opencms.file.CmsObject; 36 import org.opencms.main.CmsIllegalArgumentException; 37 import org.opencms.main.CmsRuntimeException; 38 import org.opencms.xml.types.I_CmsXmlContentValue; 39 40 import java.io.ByteArrayOutputStream ; 41 import java.io.OutputStream ; 42 import java.util.ArrayList ; 43 import java.util.Collections ; 44 import java.util.HashMap ; 45 import java.util.HashSet ; 46 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.Locale ; 49 import java.util.Map ; 50 import java.util.Set ; 51 52 import org.dom4j.Document; 53 import org.dom4j.Element; 54 import org.xml.sax.EntityResolver ; 55 56 66 public abstract class A_CmsXmlDocument implements I_CmsXmlDocument { 67 68 69 protected String m_conversion; 70 71 72 protected Document m_document; 73 74 75 protected Map m_elementLocales; 76 77 78 protected Map m_elementNames; 79 80 81 protected String m_encoding; 82 83 84 protected CmsFile m_file; 85 86 87 protected Set m_locales; 88 89 90 private Map m_bookmarks; 91 92 96 protected A_CmsXmlDocument() { 97 98 m_bookmarks = new HashMap (); 99 m_locales = new HashSet (); 100 } 101 102 109 protected static final String getBookmarkName(String name, Locale locale) { 110 111 StringBuffer result = new StringBuffer (64); 112 result.append('/'); 113 result.append(locale.toString()); 114 result.append('/'); 115 result.append(name); 116 return result.toString(); 117 } 118 119 122 public void copyLocale(Locale source, Locale destination) throws CmsXmlException { 123 124 if (!hasLocale(source)) { 125 throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_NOT_AVAILABLE_1, source)); 126 } 127 if (hasLocale(destination)) { 128 throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_ALREADY_EXISTS_1, destination)); 129 } 130 131 Element sourceElement = null; 132 Element rootNode = m_document.getRootElement(); 133 Iterator i = rootNode.elementIterator(); 134 String localeStr = source.toString(); 135 while (i.hasNext()) { 136 Element element = (Element)i.next(); 137 String language = element.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE, null); 138 if ((language != null) && (localeStr.equals(language))) { 139 sourceElement = element.createCopy(); 141 break; 143 } 144 } 145 146 if (sourceElement == null) { 147 throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_NOT_AVAILABLE_1, source)); 149 } 150 151 sourceElement.addAttribute(CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE, destination.toString()); 153 rootNode.add(sourceElement); 155 156 initDocument(m_document, m_encoding, getContentDefinition()); 158 } 159 160 168 public CmsFile correctXmlStructure(CmsObject cms) throws CmsXmlException { 169 170 Iterator i = m_locales.iterator(); 172 while (i.hasNext()) { 173 Locale locale = (Locale )i.next(); 174 List names = getNames(locale); 175 176 Iterator j = names.iterator(); 178 while (j.hasNext()) { 179 180 String name = (String )j.next(); 183 I_CmsXmlContentValue value = getValue(name, locale); 184 if (value.isSimpleType()) { 185 String content = value.getStringValue(cms); 186 value.setStringValue(cms, content); 187 } 188 } 189 } 190 191 m_file.setContents(marshal()); 193 return m_file; 194 } 195 196 201 public String getConversion() { 202 203 return m_conversion; 204 } 205 206 209 public String getEncoding() { 210 211 return m_encoding; 212 } 213 214 219 public CmsFile getFile() { 220 221 return m_file; 222 } 223 224 227 public int getIndexCount(String name, Locale locale) { 228 229 List elements = getValues(name, locale); 230 if (elements == null) { 231 return 0; 232 } else { 233 return elements.size(); 234 } 235 } 236 237 240 public List getLocales() { 241 242 return new ArrayList (m_locales); 243 } 244 245 253 public List getLocales(String name) { 254 255 Object result = m_elementLocales.get(CmsXmlUtils.createXpath(name, 1)); 256 if (result == null) { 257 return Collections.EMPTY_LIST; 258 } 259 return new ArrayList ((Set )result); 260 } 261 262 265 public List getNames(Locale locale) { 266 267 Object o = m_elementNames.get(locale); 268 if (o != null) { 269 return new ArrayList ((Set )o); 270 } 271 return Collections.EMPTY_LIST; 272 } 273 274 277 public String getStringValue(CmsObject cms, String name, Locale locale) { 278 279 I_CmsXmlContentValue value = getValueInternal(CmsXmlUtils.createXpath(name, 1), locale); 280 if (value != null) { 281 return value.getStringValue(cms); 282 } 283 return null; 284 } 285 286 289 public String getStringValue(CmsObject cms, String name, Locale locale, int index) { 290 291 I_CmsXmlContentValue value = getValueInternal(CmsXmlUtils.createXpath(name, index + 1), locale); 294 if (value != null) { 295 return value.getStringValue(cms); 296 } 297 return null; 298 } 299 300 303 public I_CmsXmlContentValue getValue(String name, Locale locale) { 304 305 return getValueInternal(CmsXmlUtils.createXpath(name, 1), locale); 306 } 307 308 311 public I_CmsXmlContentValue getValue(String name, Locale locale, int index) { 312 313 return getValueInternal(CmsXmlUtils.createXpath(name, index + 1), locale); 314 } 315 316 319 public List getValues(Locale locale) { 320 321 List result = new ArrayList (); 322 323 String prefix = '/' + locale.toString() + '/'; 325 326 Iterator i = m_bookmarks.keySet().iterator(); 328 while (i.hasNext()) { 329 String key = (String )i.next(); 330 if (key.startsWith(prefix)) { 331 result.add(m_bookmarks.get(key)); 332 } 333 } 334 335 Collections.sort(result); 337 338 return result; 339 } 340 341 344 public List getValues(String name, Locale locale) { 345 346 List result = new ArrayList (); 347 int count = 1; 348 Object o; 349 name = CmsXmlUtils.removeXpathIndex(name); 350 do { 351 String path = CmsXmlUtils.createXpathElement(name, count); 352 o = getBookmark(path, locale); 353 if (o != null) { 354 result.add(o); 355 count++; 356 } 357 } while (o != null); 358 359 return result; 360 } 361 362 365 public boolean hasLocale(Locale locale) { 366 367 if (locale == null) { 368 throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_NULL_LOCALE_0)); 369 } 370 371 return m_locales.contains(locale); 372 } 373 374 377 public boolean hasValue(String name, Locale locale) { 378 379 return null != getBookmark(CmsXmlUtils.createXpath(name, 1), locale); 380 } 381 382 385 public boolean hasValue(String name, Locale locale, int index) { 386 387 return null != getBookmark(CmsXmlUtils.createXpath(name, index + 1), locale); 388 } 389 390 393 public void initDocument() { 394 395 initDocument(m_document, m_encoding, getContentDefinition()); 396 } 397 398 401 public boolean isEnabled(String name, Locale locale) { 402 403 return hasValue(name, locale); 404 } 405 406 409 public boolean isEnabled(String name, Locale locale, int index) { 410 411 return hasValue(name, locale, index); 412 } 413 414 421 public byte[] marshal() throws CmsXmlException { 422 423 return ((ByteArrayOutputStream )marshal(new ByteArrayOutputStream (), m_encoding)).toByteArray(); 424 } 425 426 429 public void moveLocale(Locale source, Locale destination) throws CmsXmlException { 430 431 copyLocale(source, destination); 432 removeLocale(source); 433 } 434 435 438 public void removeLocale(Locale locale) throws CmsXmlException { 439 440 if (!hasLocale(locale)) { 441 throw new CmsXmlException(Messages.get().container(Messages.ERR_LOCALE_NOT_AVAILABLE_1, locale)); 442 } 443 444 Element rootNode = m_document.getRootElement(); 445 Iterator i = rootNode.elementIterator(); 446 String localeStr = locale.toString(); 447 while (i.hasNext()) { 448 Element element = (Element)i.next(); 449 String language = element.attributeValue(CmsXmlContentDefinition.XSD_ATTRIBUTE_VALUE_LANGUAGE, null); 450 if ((language != null) && (localeStr.equals(language))) { 451 element.detach(); 453 break; 455 } 456 } 457 458 initDocument(m_document, m_encoding, getContentDefinition()); 460 } 461 462 467 public void setConversion(String conversion) { 468 469 m_conversion = conversion; 470 } 471 472 475 public String toString() { 476 477 try { 478 return CmsXmlUtils.marshal(m_document, m_encoding); 479 } catch (CmsXmlException e) { 480 throw new CmsRuntimeException(Messages.get().container(Messages.ERR_WRITE_XML_DOC_TO_STRING_0), e); 481 } 482 } 483 484 493 public void validateXmlStructure(EntityResolver resolver) throws CmsXmlException { 494 495 if (m_file != null) { 496 byte[] xmlData = null; 497 xmlData = m_file.getContents(); 499 CmsXmlUtils.validateXmlStructure(xmlData, resolver); 500 } else { 501 CmsXmlUtils.validateXmlStructure(m_document, m_encoding, resolver); 502 } 503 } 504 505 513 protected void addBookmark(String name, Locale locale, boolean enabled, Object value) { 514 515 addLocale(locale); 517 518 m_bookmarks.put(getBookmarkName(name, locale), value); 520 521 Object o; 522 if (enabled) { 524 o = m_elementLocales.get(name); 526 if (o != null) { 527 ((Set )o).add(locale); 528 } else { 529 Set set = new HashSet (); 530 set.add(locale); 531 m_elementLocales.put(name, set); 532 } 533 } 534 o = m_elementNames.get(locale); 536 if (o != null) { 537 ((Set )o).add(name); 538 } else { 539 Set set = new HashSet (); 540 set.add(name); 541 m_elementNames.put(locale, set); 542 } 543 } 544 545 550 protected void addLocale(Locale locale) { 551 552 m_locales.add(locale); 554 } 555 556 559 protected void clearBookmarks() { 560 561 m_bookmarks.clear(); 562 } 563 564 573 protected Object getBookmark(String bookmark) { 574 575 return m_bookmarks.get(bookmark); 576 } 577 578 585 protected Object getBookmark(String name, Locale locale) { 586 587 return m_bookmarks.get(getBookmarkName(name, locale)); 588 } 589 590 595 protected Set getBookmarks() { 596 597 return m_bookmarks.keySet(); 598 } 599 600 607 protected abstract void initDocument(Document document, String encoding, CmsXmlContentDefinition contentDefinition); 608 609 618 protected OutputStream marshal(OutputStream out, String encoding) throws CmsXmlException { 619 620 return CmsXmlUtils.marshal(m_document, out, encoding); 621 } 622 623 630 protected I_CmsXmlContentValue removeBookmark(String name, Locale locale) { 631 632 Object o; 634 o = m_elementLocales.get(name); 635 if (o != null) { 636 ((Set )o).remove(locale); 637 } 638 o = m_elementNames.get(locale); 640 if (o != null) { 641 ((Set )o).remove(name); 642 } 643 return (I_CmsXmlContentValue)m_bookmarks.remove(getBookmarkName(name, locale)); 645 } 646 647 659 private I_CmsXmlContentValue getValueInternal(String name, Locale locale) { 660 661 Object value = getBookmark(name, locale); 662 if (value != null) { 663 return (I_CmsXmlContentValue)value; 664 } 665 return null; 666 } 667 } | Popular Tags |