001: /*
002: * Created on Oct 3, 2004
003: */
004: package org.openedit.store.xmldb;
005:
006: import java.io.File;
007: import java.io.StringWriter;
008: import java.util.ArrayList;
009: import java.util.HashMap;
010: import java.util.Iterator;
011: import java.util.List;
012: import java.util.Map;
013:
014: import org.apache.commons.logging.Log;
015: import org.apache.commons.logging.LogFactory;
016: import org.dom4j.DocumentHelper;
017: import org.dom4j.Element;
018: import org.openedit.repository.filesystem.StringItem;
019: import org.openedit.store.CatalogArchive;
020: import org.openedit.store.Category;
021: import org.openedit.store.Image;
022: import org.openedit.store.Store;
023: import org.openedit.store.StoreException;
024: import org.openedit.xml.PropertyDetails;
025:
026: import com.openedit.OpenEditException;
027: import com.openedit.OpenEditRuntimeException;
028: import com.openedit.config.Configuration;
029: import com.openedit.config.XMLConfiguration;
030: import com.openedit.page.Page;
031: import com.openedit.page.manage.PageManager;
032: import com.openedit.util.XmlUtil;
033:
034: /**
035: * @author cburkey
036: *
037: */
038: public class XmlCatalogArchive extends BaseXmlArchive implements
039: CatalogArchive {
040: private static final Log log = LogFactory
041: .getLog(XmlCatalogArchive.class);
042: protected Store fieldStore;
043: protected Map fieldCatalogMap;
044: protected Category fieldRootCatalog;
045: protected PageManager fieldPageManager;
046: protected List fieldImageList;
047: protected PropertyDetails fieldPropertyDetails;
048:
049: public List listAllCatalogs() throws StoreException {
050: List all = new ArrayList();
051: addCatalogs(all, getRootCatalog());
052: return all;
053: }
054:
055: /**
056: * @param inAll
057: * @param inRootCatalog
058: */
059: private void addCatalogs(List inAll, Category inRootCatalog) {
060: // TODO Auto-generated method stub
061: inAll.add(inRootCatalog);
062: for (Iterator iter = inRootCatalog.getChildren().iterator(); iter
063: .hasNext();) {
064: Category child = (Category) iter.next();
065: addCatalogs(inAll, child);
066: }
067: }
068:
069: public Map getCatalogMap() {
070: if (fieldCatalogMap == null) {
071: fieldCatalogMap = new HashMap();
072: }
073: return fieldCatalogMap;
074: }
075:
076: /*
077: * (non-javadoc)
078: *
079: * @see com.openedit.store.CatalogReader#getCatalog(java.lang.String)
080: */
081: public Category getCatalog(String inCategory) {
082: try {
083: getRootCatalog();
084: return (Category) getCatalogMap().get(inCategory);
085: } catch (Exception ex) {
086: throw new OpenEditRuntimeException(ex);
087: }
088: }
089:
090: public Category getCatalogByName(String inCategoryName)
091: throws StoreException {
092: List catalogs = listAllCatalogs();
093: for (Iterator iter = catalogs.iterator(); iter.hasNext();) {
094: Category catalog = (Category) iter.next();
095: if (catalog.getName().equals(inCategoryName)) {
096: return catalog;
097: }
098: }
099: return null;
100: }
101:
102: /*
103: * (non-javadoc)
104: *
105: * @see com.openedit.store.CatalogReader#getRootCatalog()
106: */
107: public Category getRootCatalog() throws StoreException {
108: if (fieldRootCatalog == null) {
109: reloadCatalogs();
110: }
111: return fieldRootCatalog;
112: }
113:
114: /**
115: * @param inCategoryId
116: * @param inCategorydesc
117: * @return
118: */
119: public Category addCatalog(String inCategoryId,
120: String inCategorydesc) throws StoreException {
121: Category oldCatalog = getCatalog(inCategoryId);
122: if (oldCatalog == null) {
123: oldCatalog = new Category();
124: oldCatalog.setId(inCategoryId);
125: oldCatalog.setName(inCategorydesc);
126: addCatalog(oldCatalog);
127: getRootCatalog().addChild(oldCatalog);
128: try {
129: Page des = getPageManager().getPage(
130: "/" + getStore().getCatalogId()
131: + "/categories/" + inCategoryId
132: + ".html");
133: if (!des.exists()) {
134: StringItem item = new StringItem(des.getPath(),
135: " ", des.getCharacterEncoding());
136: item.setMakeVersion(false);
137: des.setContentItem(item);
138: getPageManager().putPage(des);
139: }
140: } catch (Exception ex) {
141: throw new StoreException(ex);
142: }
143: } else {
144: oldCatalog.setName(inCategorydesc);
145: }
146: return oldCatalog;
147: }
148:
149: public void addCatalog(Category inCategory) throws StoreException {
150: if (inCategory == null) {
151: return;
152: }
153: boolean wasInAlready = getCatalogMap().containsKey(
154: inCategory.getId());
155:
156: getCatalogMap().put(inCategory.getId(), inCategory);
157: if (!wasInAlready && inCategory.hasChildren()) // we dont want an
158: // infinite loop so we
159: // check to see if it
160: // was in already
161: {
162: for (Iterator iter = inCategory.getChildren().iterator(); iter
163: .hasNext();) {
164: Category child = (Category) iter.next();
165: // log.info("adding " + child);
166: addCatalog(child);
167: }
168: }
169: }
170:
171: public void deleteCatalog(Category inCategory)
172: throws StoreException {
173: getCatalogMap().remove(inCategory.getId());
174: if (getRootCatalog().getId().equals(inCategory.getId())) {
175: setRootCatalog(new Category("index", "Index"));
176: } else {
177: deleteAll(inCategory);
178: if (inCategory.getParentCatalog() != null) {
179: inCategory.getParentCatalog().removeChild(inCategory);
180: }
181: }
182: saveCatalogs();
183: }
184:
185: protected void deleteAll(Category inCategory) throws StoreException {
186: for (Iterator iter = inCategory.getChildren().iterator(); iter
187: .hasNext();) {
188: Category child = (Category) iter.next();
189: child.setParentCatalog(null); // to prevent
190: // ConcurrentModificationException
191: deleteAll(child);
192: }
193: }
194:
195: public void clearCatalogs() {
196: fieldCatalogMap = null;
197: fieldRootCatalog = null;
198: }
199:
200: public void setRootCatalog(Category inRootCatalog)
201: throws StoreException {
202: fieldRootCatalog = inRootCatalog;
203: if (fieldRootCatalog != null) {
204: String home = fieldRootCatalog.getProperty("categoryhome");
205: if (home == null) {
206: fieldRootCatalog.setProperty("categoryhome", "/"
207: + getStore().getCatalogId() + "/categories/");
208: }
209: }
210: addCatalog(fieldRootCatalog);
211:
212: }
213:
214: protected String listCatalogXml() {
215: return "/" + getStore().getCatalogId()
216: + "/categories/categories.xml";
217: }
218:
219: /*
220: * (non-javadoc)
221: *
222: * @see com.openedit.store.CatalogArchive#saveCatalogs()
223: */
224: public void saveCatalogs() throws StoreException {
225: try {
226: Page catalogFile = getPageManager().getPage(
227: listCatalogXml());
228:
229: Element root = createElement(getRootCatalog());
230:
231: // lets write to a file
232: StringWriter out = new StringWriter();
233: new XmlUtil().saveXml(root, out, catalogFile
234: .getCharacterEncoding());
235: StringItem string = new StringItem(catalogFile.getPath(),
236: out.toString(), catalogFile.getCharacterEncoding());
237: string.setMakeVersion(false);
238: catalogFile.setContentItem(string);
239: getPageManager().putPage(catalogFile);
240:
241: // check on descriptions
242: /*
243: * for (Iterator iter = listAllCatalogs().iterator();
244: * iter.hasNext();) { Category cat = (Category) iter.next();
245: * saveLongDescription(cat); }
246: */
247: } catch (Exception e) {
248: throw new StoreException(e);
249: }
250:
251: }
252:
253: /**
254: * @param inRootCatalog
255: * @return
256: */
257: protected Element createElement(Category inRootCatalog)
258: throws OpenEditException {
259: Element child = DocumentHelper.createElement("catalog");
260: child.addAttribute("id", inRootCatalog.getId());
261: child.addAttribute("name", inRootCatalog.getName());
262: if (inRootCatalog.getShortDescription() != null) {
263: child.addElement("shortdescription").setText(
264: inRootCatalog.getShortDescription());
265: }
266: if (inRootCatalog.getDescription() != null) {
267: saveLongDescription(inRootCatalog);
268: }
269: // add any other attributes we might have
270: for (Iterator iter = inRootCatalog.getProperties().keySet()
271: .iterator(); iter.hasNext();) {
272: String id = (String) iter.next();
273: if (id != null && !"id".equals(id) && !"name".equals(id)) {
274: Element prop = child.addElement("property");
275: prop.addAttribute("id", id);
276: prop.setText(inRootCatalog.getProperty(id));
277: }
278: }
279: saveOptions(inRootCatalog.getOptions(), child);
280: saveRelatedCategories(inRootCatalog, child);
281:
282: for (Iterator iter = inRootCatalog.getChildren().iterator(); iter
283: .hasNext();) {
284: Category subcatalog = (Category) iter.next();
285: Element newchild = createElement(subcatalog);
286: child.add(newchild);
287: }
288:
289: return child;
290: }
291:
292: protected void saveLongDescription(Category inCategory)
293: throws StoreException {
294: try {
295: Page fulldesc = getPageManager().getPage(
296: "/" + getStore().getCatalogId() + "/categories/"
297: + inCategory.getId() + ".html");
298: if (!fulldesc.exists()) {
299: String desc = inCategory.getDescription();
300: if (desc == null || desc.trim().length() == 0) {
301: return;
302: }
303: StringItem item = new StringItem(fulldesc.getPath(),
304: desc, "UTF-8");
305: fulldesc.setContentItem(item);
306: getPageManager().putPage(fulldesc);
307: }
308: } catch (OpenEditException oee) {
309: throw new StoreException(oee);
310: }
311: }
312:
313: protected Store getStore() {
314: return fieldStore;
315: }
316:
317: protected File getStoreDirectory() {
318: return getStore().getStoreDirectory();
319: }
320:
321: public void setStore(Store inStore) {
322: fieldStore = inStore;
323: }
324:
325: /**
326: *
327: *
328: */
329: public void reloadCatalogs() throws StoreException {
330: getCatalogMap().clear();
331:
332: try {
333: Page catalogFile = getPageManager().getPage(
334: listCatalogXml());
335: if (catalogFile.exists()) {
336: try {
337: Element rootE = new XmlUtil().getXml(catalogFile
338: .getReader(), catalogFile
339: .getCharacterEncoding());
340: XMLConfiguration rootConfig = new XMLConfiguration();
341: rootConfig.populate(rootE);
342:
343: Category root = createCatalog(rootConfig);
344: setRootCatalog(root);
345: } catch (Exception ex) {
346: ex.printStackTrace();
347: throw new StoreException(ex);
348: }
349: } else {
350: log.error("No catalog file found "
351: + catalogFile.getPath());
352: Category root = new Category();
353: root.setId("index");
354: root.setName("Index");
355: setRootCatalog(root);
356: }
357: } catch (Exception ex) {
358: throw new StoreException(ex);
359: }
360: }
361:
362: /**
363: * @param inRootElement
364: * @return
365: */
366: protected Category createCatalog(Configuration inRootConfig)
367: throws OpenEditException {
368: Category cat = new Category();
369: cat.setId(inRootConfig.getAttribute("id"));
370: if (cat.getId() == null) {
371: log.error("Corrupt catalog with no id");
372: }
373: cat.setName(inRootConfig.getAttribute("name"));
374: for (Iterator iter = inRootConfig.getAttributeNames()
375: .iterator(); iter.hasNext();) {
376: String attrName = (String) iter.next();
377: if (!attrName.equals("id") && !attrName.equals("name")) {
378: cat.setProperty(attrName, inRootConfig
379: .getAttribute(attrName));
380: }
381: }
382: // Also supports property
383: for (Iterator iter = inRootConfig.getChildren("property")
384: .iterator(); iter.hasNext();) {
385: Configuration config = (Configuration) iter.next();
386: cat.setProperty(config.getAttribute("id"), config
387: .getValue());
388: }
389:
390: String shortdesc = inRootConfig
391: .getChildValue("shortdescription");
392: cat.setShortDescription(shortdesc);
393:
394: loadOptions(cat, inRootConfig);
395: loadRelatedCategoryIds(cat, inRootConfig);
396: for (Iterator iter = inRootConfig.getChildren("catalog")
397: .iterator(); iter.hasNext();) {
398: Configuration config = (Configuration) iter.next();
399: cat.addChild(createCatalog(config));
400: }
401: return cat;
402: }
403:
404: protected void loadOptions(Category inCategory,
405: Configuration inConfig) {
406: inCategory.clearOptions();
407: for (Iterator iter = inConfig.getChildren("option").iterator(); iter
408: .hasNext();) {
409: Configuration optionConfig = (Configuration) iter.next();
410: inCategory.addOption(createOption(optionConfig));
411: }
412: }
413:
414: protected void loadRelatedCategoryIds(Category inCategory,
415: Configuration inProductConfig) {
416: inCategory.clearRelatedCategoryIds();
417: Configuration relatedProductsElem = inProductConfig
418: .getChild("related-categories");
419: if (relatedProductsElem != null) {
420: for (Iterator iter = relatedProductsElem
421: .getChildIterator("category"); iter.hasNext();) {
422: Configuration relatedProdConfig = (Configuration) iter
423: .next();
424: inCategory.addRelatedCategoryId(relatedProdConfig
425: .getAttribute("id"));
426: }
427: }
428: Configuration linkedToElem = inProductConfig
429: .getChild("linkedtocategory");
430: if (linkedToElem != null) {
431: inCategory.setLinkedToCategoryId(linkedToElem
432: .getAttribute("id"));
433: } else {
434: inCategory.setLinkedToCategoryId(null);
435: }
436:
437: }
438:
439: protected void saveRelatedCategories(Category inCategory,
440: Element inCategoryElement) {
441: deleteElements(inCategoryElement, "related-categories");
442: if (inCategory.getRelatedCategoryIds().size() > 0) {
443: Element relatedProductsElem = inCategoryElement
444: .addElement("related-categories");
445: for (Iterator iter = inCategory.getRelatedCategoryIds()
446: .iterator(); iter.hasNext();) {
447: String relatedProductId = (String) iter.next();
448: relatedProductsElem.addElement("category")
449: .addAttribute("id", relatedProductId);
450: }
451: }
452: deleteElements(inCategoryElement, "linkedtocategory");
453: if (inCategory.getLinkedToCategoryId() != null) {
454: Element linkedToElem = inCategoryElement
455: .addElement("linkedtocategory");
456: if (linkedToElem != null) {
457: linkedToElem.addAttribute("id", inCategory
458: .getLinkedToCategoryId());
459: }
460: }
461: }
462:
463: /*
464: * (non-javadoc)
465: *
466: * @see com.openedit.store.CatalogArchive#listNonUserSelectedCatalogs()
467: */
468: public List listNonUserSelectedCatalogs() throws StoreException {
469: List sublist = new ArrayList();
470: for (Iterator iter = listAllCatalogs().iterator(); iter
471: .hasNext();) {
472: Category cat = (Category) iter.next();
473: if (!cat.isUserSelected()) {
474: sublist.add(cat);
475: }
476: }
477: return sublist;
478: }
479:
480: public List listUserSelectedCatalogs() throws StoreException {
481: List sublist = new ArrayList();
482: for (Iterator iter = listAllCatalogs().iterator(); iter
483: .hasNext();) {
484: Category cat = (Category) iter.next();
485: if (cat.isUserSelected()) {
486: sublist.add(cat);
487: }
488: }
489: return sublist;
490: }
491:
492: public PageManager getPageManager() {
493: return fieldPageManager;
494: }
495:
496: public void setPageManager(PageManager inPageManager) {
497: fieldPageManager = inPageManager;
498: }
499:
500: public void saveCategory(Category inCategory) throws StoreException {
501: if (inCategory.getParentCatalog() == null) {
502: addCatalog(inCategory);
503: } else {
504: updateCache(inCategory);
505: }
506: saveCatalogs();
507: }
508:
509: protected void updateCache(Category inCat) {
510: getCatalogMap().put(inCat.getId(), inCat);
511: for (Iterator iterator = inCat.getChildren().iterator(); iterator
512: .hasNext();) {
513: Category child = (Category) iterator.next();
514: updateCache(child);
515: }
516: }
517:
518: /**
519: * @deprecated use saveCategory
520: */
521: public void saveCatalog(Category inCategory) throws StoreException {
522: saveCategory(inCategory);
523: }
524:
525: /**
526: * Returns a list of potential (not actual) images, valid for any catalog.
527: *
528: * @return A {@link List} of {@link Image}s
529: */
530: public List getImageList() throws StoreException {
531: if (fieldImageList == null) {
532:
533: List arrayList = new ArrayList();
534: try {
535: Page config = getPageManager().getPage(
536: "/" + getStore().getCatalogId()
537: + "/configuration/imagelist.xml");
538:
539: Element root = new XmlUtil().getXml(config.getReader(),
540: "UTF-8");
541: for (Iterator iter = root.elementIterator("image"); iter
542: .hasNext();) {
543: Element type = (Element) iter.next();
544: String name = type.attributeValue("name");
545: String id = type.attributeValue("id");
546:
547: String postfix = type.attributeValue("postfix");
548: int width = Integer.parseInt(type
549: .attributeValue("width"));
550: String sizetype = type.attributeValue("type");
551: Image thumb = new Image(name, width, postfix);
552: thumb.setId(id);
553: thumb.setType(sizetype);
554: arrayList.add(thumb);
555: }
556: } catch (Exception ex) {
557: throw new StoreException(ex);
558: }
559: fieldImageList = arrayList;
560: }
561: return fieldImageList;
562: }
563:
564: public List getImageList(String inType) throws StoreException {
565: List r = new ArrayList();
566: List items = getImageList();
567: for (Iterator iter = items.iterator(); iter.hasNext();) {
568: Image image = (Image) iter.next();
569: if (image.getType().equals(inType)) {
570: r.add(image);
571: }
572: }
573: return r;
574: }
575:
576: public PropertyDetails getCatalogDetails() throws StoreException {
577: if (fieldPropertyDetails == null) {
578: fieldPropertyDetails = new PropertyDetails();
579: // load up another xml file
580: try {
581: Page page = getPageManager()
582: .getPage(
583: "/"
584: + getStore().getCatalogId()
585: + "/configuration/categoryproperties.xml");
586: if (page.exists()) {
587: fieldPropertyDetails
588: .addAllDetails(page.getReader());
589: }
590: } catch (Exception ex) {
591: throw new StoreException(ex);
592: }
593: }
594: return fieldPropertyDetails;
595: }
596:
597: }
|