001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019:
020: package org.openharmonise.dav.server.apm;
021:
022: import java.io.*;
023: import java.util.*;
024: import java.util.logging.*;
025:
026: import javax.xml.parsers.*;
027:
028: import org.openharmonise.commons.dsi.*;
029: import org.openharmonise.commons.net.*;
030: import org.openharmonise.commons.xml.*;
031: import org.openharmonise.commons.xml.namespace.*;
032: import org.openharmonise.dav.server.utils.*;
033: import org.openharmonise.rm.*;
034: import org.openharmonise.rm.DataAccessException;
035: import org.openharmonise.rm.config.*;
036: import org.openharmonise.rm.dsi.*;
037: import org.openharmonise.rm.factory.*;
038: import org.openharmonise.rm.metadata.*;
039: import org.openharmonise.rm.resources.*;
040: import org.openharmonise.rm.resources.content.*;
041: import org.openharmonise.rm.resources.content.utils.*;
042: import org.openharmonise.rm.resources.lifecycle.*;
043: import org.openharmonise.rm.resources.metadata.properties.*;
044: import org.openharmonise.rm.resources.metadata.values.*;
045: import org.openharmonise.rm.resources.publishing.*;
046: import org.openharmonise.rm.resources.users.*;
047: import org.openharmonise.rm.resources.workflow.properties.*;
048: import org.openharmonise.rm.resources.workflow.properties.ranges.*;
049: import org.openharmonise.rm.resources.workflow.values.*;
050: import org.openharmonise.rm.resources.xml.*;
051: import org.openharmonise.rm.workflow.*;
052: import org.w3c.dom.*;
053: import org.xml.sax.*;
054:
055: /**
056: * Standard APM for Harmonise webdav layer which creates thumbnails for images as
057: * images are loaded in to system, translates DAV path references to Harmonise path
058: * references in XML content, handles creation of <code>WorkflowStageGroup<code>s
059: * for new <code>WorkflowProperty</code> objects and checks for completion of
060: * defined workflows before the status change of resources.
061: *
062: * @author Michael Bell
063: * @version $Revision: 1.7 $
064: *
065: */
066: public class StandardAPM implements AuxillaryProcessManager {
067:
068: private static final String ATTRIB_HREF = "href";
069: protected static final String PNAME_IMAGE_THUMBNAIL_SIZE = "IMAGE_THUMBNAIL_SIZE";
070:
071: private static final String PROPNAME_WORKFLOW_PROP_RELN = "workflow_prop";
072: protected static final String SECTION_CONVERSION = "conversions";
073: protected static final String PROPNAME_THUMBNAIL = "thumbnail";
074: protected static final String PROPNAME_LOWRES = "lowres";
075: protected static final String MIMETYPE_THUMBNAIL = "image/png";
076: protected static final String MIMETYPE_LOWRES = "image/jpg";
077: protected int m_nSizeThumbnail = 50;
078:
079: {
080: try {
081: m_nSizeThumbnail = ConfigSettings.getIntProperty(
082: PNAME_IMAGE_THUMBNAIL_SIZE, "50");
083: } catch (ConfigException e) {
084: m_logger.log(Level.WARNING,
085: "Ignoring config exception for thumbnail size", e);
086: }
087: }
088:
089: protected AbstractDataStoreInterface m_dsi = null;
090:
091: /**
092: * Logger for this class
093: */
094: private static final Logger m_logger = Logger
095: .getLogger(StandardAPM.class.getName());
096:
097: /**
098: *
099: */
100: public StandardAPM() throws DataStoreException {
101: super ();
102:
103: m_dsi = DataStoreInterfaceFactory.getDataStoreInterface();
104:
105: }
106:
107: /* (non-Javadoc)
108: * @see org.openharmonise.dav.server.apm.AuxillaryProcessManager#save(org.openharmonise.rm.resources.users.User, org.openharmonise.rm.resources.AbstractChildObject)
109: */
110: public void save(User usr, AbstractChildObject obj)
111: throws APMException {
112:
113: try {
114:
115: if (obj instanceof WorkflowProperty) {
116: WorkflowProperty prop = (WorkflowProperty) obj;
117:
118: String sPath = prop.getFullPath();
119:
120: sPath = sPath.replaceAll("/root/workflow",
121: "/root/workflow_defs");
122:
123: WorkflowStageValueGroup valGrp = (WorkflowStageValueGroup) HarmoniseObjectFactory
124: .instantiateHarmoniseObject(
125: m_dsi,
126: WorkflowStageValueGroup.class.getName(),
127: sPath);
128:
129: if (valGrp == null) {
130:
131: valGrp = (WorkflowStageValueGroup) getWorkflowValueGroup(sPath);
132:
133: prop.setWorkflowValueGroup(valGrp);
134:
135: prop.save();
136: }
137: }
138: } catch (DataAccessException e) {
139: throw new APMException(e.getLocalizedMessage(), e);
140: } catch (EditException e) {
141: throw new APMException(e.getLocalizedMessage(), e);
142: } catch (HarmoniseFactoryException e) {
143: throw new APMException(e.getLocalizedMessage(), e);
144: } catch (InvalidChildException e) {
145: throw new APMException(e.getLocalizedMessage(), e);
146: } catch (PopulateException e) {
147: throw new APMException(e.getLocalizedMessage(), e);
148: } catch (InvalidNameException e) {
149: throw new APMException(e.getLocalizedMessage(), e);
150: }
151:
152: }
153:
154: /* (non-Javadoc)
155: * @see org.openharmonise.dav.server.apm.AuxillaryProcessManager#delete(org.openharmonise.rm.resources.users.User, org.openharmonise.rm.resources.lifecycle.Editable)
156: */
157: public void delete(User usr, Editable obj) throws APMException {
158:
159: try {
160: if (obj instanceof Asset
161: && ((Asset) obj).getContentType().startsWith(
162: "image")) {
163:
164: Profile prof = ((AbstractProfiledObject) obj)
165: .getProfile();
166:
167: if (prof != null) {
168: ChildObjectPropertyInstance propInst = (ChildObjectPropertyInstance) prof
169: .getPropertyInstance(PROPNAME_THUMBNAIL);
170:
171: if (propInst != null && propInst.hasValues()) {
172: Asset thumb = (Asset) propInst.getValue();
173:
174: thumb.archive();
175: }
176: }
177: } else if (obj instanceof WorkflowStageValue) {
178: WorkflowStageValue stage = (WorkflowStageValue) obj;
179:
180: if (stage.getPath().startsWith("/root/workflow_stages")) {
181: stage.removeAllInstances();
182: }
183: }
184: } catch (DataAccessException e) {
185: throw new APMException(e.getLocalizedMessage(), e);
186: } catch (EditException e) {
187: throw new APMException(e.getLocalizedMessage(), e);
188: } catch (InvalidPropertyInstanceException e) {
189: throw new APMException(e.getLocalizedMessage(), e);
190: }
191:
192: }
193:
194: /* (non-Javadoc)
195: * @see org.openharmonise.dav.server.apm.AuxillaryProcessManager#saveProperties(org.openharmonise.rm.resources.users.User, org.openharmonise.rm.resources.lifecycle.Editable, org.openharmonise.rm.metadata.Profile)
196: */
197: public void saveProperties(User usr, Editable obj, Profile pro)
198: throws APMException {
199: //nothing to do
200:
201: }
202:
203: /* (non-Javadoc)
204: * @see org.openharmonise.dav.server.apm.AuxillaryProcessManager#isChangeStatusValid(org.openharmonise.rm.resources.users.User, org.openharmonise.rm.resources.lifecycle.Editable)
205: */
206: public boolean isChangeStatusValid(User usr, Editable obj)
207: throws APMException {
208: boolean bIsValid = true;
209:
210: try {
211: if (obj instanceof AbstractProfiledObject) {
212: AbstractProfiledObject profObj = (AbstractProfiledObject) obj;
213:
214: List wrkflwProps = WorkflowProfile
215: .getAvailableWorkflowProperties(profObj);
216:
217: if (wrkflwProps.size() > 0) {
218: Profile wrkflwProf = profObj
219: .getProfile(WorkflowProfile.WORKFLOW_PROFILE_NAME);
220:
221: if (wrkflwProf != null
222: && wrkflwProf.getPropertyInstances().size() > 0) {
223: Iterator iter = wrkflwProps.iterator();
224:
225: while (iter.hasNext() && bIsValid == true) {
226: WorkflowProperty tmpProp = (WorkflowProperty) iter
227: .next();
228:
229: WorkflowPropertyInstance propInst = (WorkflowPropertyInstance) wrkflwProf
230: .getPropertyInstance(tmpProp);
231:
232: if (propInst != null) {
233: bIsValid = propInst.isComplete();
234: } else {
235: bIsValid = false;
236: }
237: }
238: } else {
239: //must check if any workflow stages are mandatory
240: WorkflowProperty wrkflwProp = (WorkflowProperty) wrkflwProps
241: .get(0);
242:
243: WorkflowRange range = (WorkflowRange) wrkflwProp
244: .getRange();
245:
246: List stages = range.getAvailableValues();
247:
248: Iterator iter = stages.iterator();
249:
250: while (iter.hasNext()) {
251: WorkflowStageValue stage = (WorkflowStageValue) iter
252: .next();
253: if (stage.isMandatory()) {
254: bIsValid = false;
255: break;
256: }
257: }
258:
259: }
260: }
261: }
262: } catch (DataAccessException e) {
263: throw new APMException(e.getLocalizedMessage(), e);
264: } catch (InvalidPropertyInstanceException e) {
265: throw new APMException(e.getLocalizedMessage(), e);
266: }
267:
268: return bIsValid;
269: }
270:
271: /* (non-Javadoc)
272: * @see org.openharmonise.dav.server.apm.AuxillaryProcessManager#changeStatus(org.openharmonise.rm.resources.users.User, org.openharmonise.rm.resources.lifecycle.Editable, org.openharmonise.rm.resources.lifecycle.Status, org.openharmonise.rm.resources.lifecycle.Status)
273: */
274: public void changeStatus(User usr, Editable obj,
275: Status startStatus, Status newStatus) throws APMException {
276:
277: try {
278: if (obj instanceof Asset) {
279: changeAssetStatus(usr, (Asset) obj, startStatus,
280: newStatus);
281: } else if (obj instanceof XMLResource) {
282: changeXMLResourceStatus(usr, (XMLResource) obj,
283: startStatus, newStatus);
284: } else if (obj instanceof ValueGroup) {
285:
286: }
287: } catch (DataAccessException e) {
288: throw new APMException(e.getLocalizedMessage(), e);
289: } catch (InvalidProfileException e) {
290: throw new APMException(e.getLocalizedMessage(), e);
291: } catch (InvalidXMLContentException e) {
292: throw new APMException(e);
293: } catch (InvalidPropertyValueException e) {
294: throw new APMException(e.getLocalizedMessage(), e);
295: } catch (PopulateException e) {
296: throw new APMException(e.getLocalizedMessage(), e);
297: } catch (EditException e) {
298: throw new APMException(e.getLocalizedMessage(), e);
299: } catch (HarmoniseFactoryException e) {
300: throw new APMException(e.getLocalizedMessage(), e);
301: } catch (ProfileException e) {
302: throw new APMException(e.getLocalizedMessage(), e);
303: } catch (InvalidChildException e) {
304: throw new APMException(e.getLocalizedMessage(), e);
305: } catch (Exception e) {
306: throw new APMException(e.getLocalizedMessage(), e);
307: }
308:
309: }
310:
311: protected Section getConversionsSection(Section parent)
312: throws APMException {
313: Section secConversion;
314: try {
315: StringBuffer sPath = new StringBuffer(parent.getFullPath());
316: sPath.append(AbstractParentObject.separator);
317: sPath.append(SECTION_CONVERSION);
318:
319: secConversion = (Section) HarmoniseObjectFactory
320: .instantiateHarmoniseObject(m_dsi, Section.class
321: .getName(), sPath.toString());
322:
323: if (secConversion == null) {
324: secConversion = new Section(m_dsi);
325: secConversion.setName(SECTION_CONVERSION);
326:
327: Profile secProf = new Profile(m_dsi);
328: secConversion.setProfile(secProf);
329:
330: secConversion = (Section) secConversion.save();
331:
332: parent.acquireEditWriteLock();
333: try {
334: parent.addChild(secConversion);
335:
336: parent.save();
337: } finally {
338: parent.releaseEditWriteLock();
339: }
340:
341: secConversion.changeStatus(Status.APPROVED);
342: }
343: } catch (DataAccessException e) {
344: throw new APMException(e.getLocalizedMessage(), e);
345: } catch (HarmoniseFactoryException e) {
346: throw new APMException(e.getLocalizedMessage(), e);
347: } catch (InvalidProfileException e) {
348: throw new APMException(e.getLocalizedMessage(), e);
349: } catch (EditException e) {
350: throw new APMException(e.getLocalizedMessage(), e);
351: } catch (InvalidChildException e) {
352: throw new APMException(e.getLocalizedMessage(), e);
353: } catch (PopulateException e) {
354: throw new APMException(e.getLocalizedMessage(), e);
355: } catch (InvalidNameException e) {
356: throw new APMException(e.getLocalizedMessage(), e);
357: }
358:
359: return secConversion;
360: }
361:
362: protected void updateAsset(Asset thumb, Asset asset, String sType,
363: int nSize) throws APMException {
364: try {
365: File fileNew = ImageConverter.convertImage(asset
366: .getContentFile(), "thumb",
367: (String) MimeTypeMapping.getExtensions(sType)
368: .get(0), nSize);
369:
370: thumb.setContentFile(fileNew);
371:
372: Asset unapprovedAsset = (Asset) thumb.save();
373: unapprovedAsset.ignoreProfileRestrictions(true);
374: unapprovedAsset.changeStatus(Status.APPROVED);
375: } catch (DataAccessException e) {
376: throw new APMException(e.getLocalizedMessage(), e);
377: } catch (PopulateException e) {
378: throw new APMException(e.getLocalizedMessage(), e);
379: } catch (EditException e) {
380: throw new APMException(e.getLocalizedMessage(), e);
381: } catch (Exception e) {
382: throw new APMException(e.getLocalizedMessage(), e);
383: }
384: }
385:
386: protected void updateAsset(Asset thumb, Asset asset, String sType)
387: throws Exception {
388: File fileNew = ImageConverter.convertImage(asset
389: .getContentFile(), "thumb", (String) MimeTypeMapping
390: .getExtensions(sType).get(0));
391: thumb.setContentFile(fileNew);
392:
393: Asset unapprovedAsset = (Asset) thumb.save();
394: unapprovedAsset.ignoreProfileRestrictions(true);
395: unapprovedAsset.changeStatus(Status.APPROVED);
396: }
397:
398: public String getContent(User user, TextResource txtResource,
399: Status status) throws APMException {
400: // now pre-process the content of the resource
401: String sContent = null;
402:
403: try {
404: sContent = txtResource.getContent(); // get the content
405:
406: // if this is an XMLResource or a Template, then
407: // check if the status is approved and pre-process the content
408: // if it is.
409: if ((txtResource instanceof XMLResource || txtResource instanceof Template)
410: && status.equals(Status.APPROVED)) {
411:
412: org.w3c.dom.Document doc = ((XMLResource) txtResource)
413: .getDocument();
414:
415: // get all the path nodes
416: NodeList pathNodes = doc
417: .getElementsByTagName(AbstractChildObject.TAG_PATH);
418: Element curElm = null;
419:
420: Element parentEl = null;
421:
422: for (int i = 0; i < pathNodes.getLength(); i++) {
423: curElm = (Element) pathNodes.item(i); // get the current path
424: Text pathText = (Text) curElm.getFirstChild(); // get the first child
425: if (pathText != null) {
426: parentEl = (Element) curElm.getParentNode();
427: String sDavPath = HarmoniseNameResolver
428: .getDAVPath(m_dsi, pathText.getData());
429:
430: if (sDavPath != null) {
431: pathText.setData(sDavPath);
432: }
433: }
434: }
435:
436: NodeList xincludes = doc.getElementsByTagNameNS(
437: NamespaceType.XINCLUDE.getURI(), "include");
438:
439: for (int i = 0; i < xincludes.getLength(); i++) {
440: curElm = (Element) xincludes.item(i);
441: // get the current path
442: Attr hrefAttr = (Attr) curElm
443: .getAttributeNode(ATTRIB_HREF);
444: // get the first child
445: hrefAttr.setValue(HarmoniseNameResolver
446: .getDAVPath(txtResource.getClass(),
447: hrefAttr.getValue()));
448: }
449:
450: XMLPrettyPrint xmlPrettyPrint = new XMLPrettyPrint();
451: xmlPrettyPrint.setNamespaceAware(true);
452: sContent = xmlPrettyPrint.printNode(doc);
453: }
454: } catch (DataAccessException e) {
455: throw new APMException(e.getLocalizedMessage(), e);
456: } catch (FactoryConfigurationError e) {
457: throw new APMException(e.getLocalizedMessage(), e);
458: } catch (NamespaceClashException e) {
459: throw new APMException(e.getLocalizedMessage(), e);
460: } catch (DOMException e) {
461: throw new APMException(e.getLocalizedMessage(), e);
462: } catch (NameResolverException e) {
463: throw new APMException(e.getLocalizedMessage(), e);
464: }
465:
466: return sContent;
467: }
468:
469: protected void changeAssetStatus(User usr, Asset asset,
470: Status startStatus, Status newStatus)
471: throws DataAccessException, InvalidProfileException,
472: PopulateException, EditException, InvalidChildException,
473: HarmoniseFactoryException, InvalidPropertyValueException,
474: ProfileException, APMException, Exception {
475:
476: if (asset.getContentType().startsWith("image")
477: && (startStatus == Status.UNAPPROVED)
478: && (newStatus == Status.APPROVED)) {
479:
480: if (m_logger.isLoggable(Level.FINE)) {
481: m_logger.logp(Level.FINE, this .getClass().getName(),
482: "changeAssetStatus", "Approving asset "
483: + asset.getName());
484: }
485:
486: String sContentType = asset.getContentType();
487: Profile prof = asset.getProfile();
488:
489: Section secConversions = getConversionsSection((Section) asset
490: .getRealParent());
491:
492: Asset unApprovedAsset = asset;
493: boolean bIsChanged = false;
494:
495: //add the low res version
496: try {
497: AbstractPropertyInstance lowresPropInst = prof
498: .getPropertyInstance(PROPNAME_LOWRES);
499:
500: if (sContentType.equals("image/tif")) {
501: if (lowresPropInst == null) {
502: if (m_logger.isLoggable(Level.FINE)) {
503: m_logger.log(Level.FINE,
504: "Creating lowres image");
505: }
506:
507: Asset lowres = createLowRes(asset,
508: secConversions);
509:
510: Property prop = PropertyFactory
511: .getPropertyFromName(m_dsi,
512: PROPNAME_LOWRES);
513:
514: lowresPropInst = PropertyInstanceFactory
515: .getPropertyInstance(m_dsi, prop);
516:
517: ((ChildObjectPropertyInstance) lowresPropInst)
518: .addValue(lowres);
519:
520: prof.addPropertyInstance(lowresPropInst);
521:
522: unApprovedAsset = (Asset) asset.save();
523: bIsChanged = true;
524: } else {
525: updateAsset((Asset) lowresPropInst.getValue(),
526: asset, MIMETYPE_LOWRES);
527: }
528: }
529: } catch (InvalidPropertyInstanceException e) {
530: if (m_logger.isLoggable(Level.INFO)) {
531: m_logger.logp(Level.INFO,
532: this .getClass().getName(),
533: "changeAssetStatus", PROPNAME_LOWRES
534: + " is invalid on this asset");
535: }
536: }
537:
538: //add the thumbnail version
539: try {
540: AbstractPropertyInstance thumbPropInst = prof
541: .getPropertyInstance(PROPNAME_THUMBNAIL);
542:
543: if (ImageConverter.getImageHeight(asset
544: .getContentFile()) > m_nSizeThumbnail) {
545:
546: if (thumbPropInst == null) {
547: if (m_logger.isLoggable(Level.FINE)) {
548: m_logger.log(Level.FINE,
549: "Creating thumbnail image");
550: }
551:
552: Asset thumb = createThumbnail(asset,
553: secConversions);
554:
555: Property prop = PropertyFactory
556: .getPropertyFromName(m_dsi,
557: PROPNAME_THUMBNAIL);
558:
559: thumbPropInst = PropertyInstanceFactory
560: .getPropertyInstance(m_dsi, prop);
561:
562: ((ChildObjectPropertyInstance) thumbPropInst)
563: .addValue(thumb);
564:
565: if (unApprovedAsset != null) {
566: unApprovedAsset.getProfile()
567: .addPropertyInstance(thumbPropInst);
568:
569: unApprovedAsset = (Asset) unApprovedAsset
570: .save();
571: } else {
572: prof.addPropertyInstance(thumbPropInst);
573: unApprovedAsset = (Asset) asset.save();
574: }
575:
576: bIsChanged = true;
577:
578: } else {
579: updateAsset((Asset) thumbPropInst.getValue(),
580: asset, MIMETYPE_THUMBNAIL,
581: m_nSizeThumbnail);
582: }
583: }
584: } catch (InvalidPropertyInstanceException e) {
585: if (m_logger.isLoggable(Level.INFO)) {
586: m_logger.logp(Level.INFO,
587: this .getClass().getName(),
588: "changeAssetStatus", PROPNAME_THUMBNAIL
589: + " is invalid on this asset");
590: }
591: }
592:
593: //finally approve the new version of the asset
594: if (bIsChanged == true) {
595: unApprovedAsset.changeStatus(Status.APPROVED);
596: }
597: }
598: }
599:
600: /**
601: * Create new thumbnail version of the specified image asset and place
602: * it in the specified collection
603: *
604: * @param asset
605: * @param secConversions
606: * @return
607: * @throws DataAccessException
608: * @throws InvalidNameException
609: * @throws InvalidProfileException
610: * @throws Exception
611: * @throws PopulateException
612: * @throws EditException
613: * @throws InvalidChildException
614: */
615: private Asset createThumbnail(Asset asset, Section secConversions)
616: throws DataAccessException, InvalidNameException,
617: InvalidProfileException, Exception, PopulateException,
618: EditException, InvalidChildException {
619: StringBuffer sNewName = new StringBuffer(asset.getName());
620: sNewName.append("_thumbnail");
621:
622: Asset thumb = new Asset(m_dsi);
623: thumb.setName(sNewName.toString());
624: thumb.setSummary(asset.getSummary());
625:
626: Profile newProf = new Profile(m_dsi);
627: thumb.addProfile(newProf);
628:
629: File fileMain = asset.getContentFile();
630: String sPath = asset.getContentFile().getAbsolutePath();
631: String sNewFileName = sPath.substring(0, sPath.indexOf("."))
632: + "_thumb";
633:
634: File fileNew = ImageConverter.convertImage(fileMain,
635: MimeTypeMapping
636: .getExtensionFromMimeType(MIMETYPE_THUMBNAIL),
637: sNewFileName, m_nSizeThumbnail);
638:
639: thumb.setContentFile(fileNew);
640:
641: if (m_logger.isLoggable(Level.FINE)) {
642: m_logger.log(Level.FINE,
643: "Conversion section for new thumbnail is "
644: + secConversions.toString());
645: }
646:
647: thumb = (Asset) thumb.save();
648:
649: secConversions.addChild(thumb);
650: secConversions.save();
651: thumb.ignoreProfileRestrictions(true);
652:
653: thumb.changeStatus(Status.APPROVED);
654: return thumb;
655: }
656:
657: /**
658: * Create new low resolution image for this specified image asset and place it
659: * in the specified collection
660: *
661: * @param asset
662: * @param secConversions
663: * @return
664: * @throws DataAccessException
665: * @throws InvalidNameException
666: * @throws InvalidProfileException
667: * @throws Exception
668: * @throws PopulateException
669: * @throws EditException
670: */
671: private Asset createLowRes(Asset asset, Section secConversions)
672: throws DataAccessException, InvalidNameException,
673: InvalidProfileException, Exception, PopulateException,
674: EditException {
675: StringBuffer sNewName = new StringBuffer(asset.getName());
676: sNewName.append("_lowres");
677:
678: Asset lowres = new Asset(m_dsi);
679: lowres.setName(sNewName.toString());
680: lowres.setSummary(asset.getSummary());
681:
682: Profile newProf = new Profile(m_dsi);
683: lowres.addProfile(newProf);
684:
685: File fileMain = asset.getContentFile();
686: String sPath = asset.getContentFile().getAbsolutePath();
687: String sNewFileName = sPath.substring(0, sPath.indexOf("."))
688: + "_lowres";
689:
690: File fileNew = ImageConverter.convertImage(fileMain,
691: sNewFileName, MimeTypeMapping
692: .getExtensionFromMimeType(MIMETYPE_LOWRES));
693:
694: lowres.setContentFile(fileNew);
695:
696: if (m_logger.isLoggable(Level.FINE)) {
697: m_logger.log(Level.FINE,
698: "Conversion section for new lowres image is "
699: + secConversions.toString());
700: }
701:
702: lowres = (Asset) lowres.save();
703:
704: secConversions.acquireEditWriteLock();
705: try {
706: secConversions.addChild(lowres);
707: secConversions.save();
708:
709: } finally {
710: secConversions.releaseEditWriteLock();
711: }
712: lowres.ignoreProfileRestrictions(true);
713:
714: lowres = (Asset) lowres.changeStatus(Status.APPROVED);
715:
716: return lowres;
717: }
718:
719: private void changeXMLResourceStatus(User usr, XMLResource xml,
720: Status startStatus, Status newStatus)
721: throws DataAccessException, SAXException, IOException,
722: ParserConfigurationException, FactoryConfigurationError,
723: DOMException, NameResolverException,
724: NamespaceClashException, EditException, PopulateException {
725: if ((startStatus == Status.UNAPPROVED)
726: && (newStatus == Status.APPROVED)) {
727: boolean bHasChanged = false;
728:
729: if (m_logger.isLoggable(Level.FINE)) {
730: m_logger.logp(Level.FINE, this .getClass().getName(),
731: "changeXMLResourceStatus",
732: "Approving TextResource " + xml.getName());
733: }
734:
735: String sContentType = xml.getContentType();
736:
737: org.w3c.dom.Document doc = xml.getDocument();
738:
739: // get all the path nodes
740: NodeList pathNodes = doc
741: .getElementsByTagName(AbstractChildObject.TAG_PATH);
742: Element curElm = null;
743:
744: for (int i = 0; i < pathNodes.getLength(); i++) {
745: curElm = (Element) pathNodes.item(i);
746: // get the current path
747: Text pathText = (Text) curElm.getFirstChild();
748: if (pathText != null) {
749: String sPath = pathText.getData();
750: //ignore relative paths, which don't start with a '/'
751: //and ignore non-DAV paths which don't need translated
752: if (sPath
753: .startsWith(HarmoniseNameResolver.URL_SEPARATOR)
754: && HarmoniseNameResolver.isDAVPath(sPath)) {
755: // get the first child
756: pathText.setData(HarmoniseNameResolver
757: .getRealPath(sPath));
758: bHasChanged = true;
759: }
760: }
761: }
762:
763: NodeList xincludes = doc.getElementsByTagNameNS(
764: NamespaceType.XINCLUDE.getURI(), "include");
765:
766: for (int i = 0; i < xincludes.getLength(); i++) {
767: curElm = (Element) xincludes.item(i);
768: // get the current path
769: Attr hrefAttr = (Attr) curElm
770: .getAttributeNode(ATTRIB_HREF);
771: // get the first child
772: hrefAttr.setValue(HarmoniseNameResolver
773: .getRealPath(hrefAttr.getValue()));
774: bHasChanged = true;
775: }
776:
777: //only changed content and save if paths or includes were picked up
778: if (bHasChanged == true) {
779: XMLPrettyPrint xmlPrettyPrint = new XMLPrettyPrint();
780: xmlPrettyPrint.setNamespaceAware(true);
781: String sContent = xmlPrettyPrint.printNode(doc);
782:
783: xml.setContent(sContent);
784: xml.save().changeStatus(Status.APPROVED);
785: }
786: }
787: }
788:
789: private void changeValueGroupStatus(User usr, ValueGroup valGrp,
790: Status startStatus, Status newStatus) throws EditException,
791: InvalidChildException, PopulateException,
792: HarmoniseFactoryException, InvalidPropertyValueException,
793: ProfileException, InvalidNameException, DataAccessException {
794: if (valGrp instanceof WorkflowStageValueGroup) {
795: if (startStatus == Status.UNAPPROVED
796: && newStatus == Status.APPROVED) {
797:
798: List children = valGrp.getChildren();
799:
800: //if grp has children that are workflow stages then
801: //create prop
802: if (children.size() > 0
803: && children.get(0) instanceof WorkflowStageValue) {
804: Profile prof = valGrp.getProfile();
805:
806: Property wrkflwRelnProp = PropertyFactory
807: .getPropertyFromName(m_dsi,
808: PROPNAME_WORKFLOW_PROP_RELN);
809:
810: AbstractPropertyInstance propInst = prof
811: .getPropertyInstance(wrkflwRelnProp);
812:
813: if (propInst == null) {
814: WorkflowProperty prop = new WorkflowProperty(
815: m_dsi);
816: prop.setName(valGrp.getName());
817: prop
818: .setWorkflowValueGroup((WorkflowStageValueGroup) valGrp);
819: prop.save();
820:
821: String sParentPath = valGrp.getPath();
822:
823: WorkflowPropertyGroup propGrp = (WorkflowPropertyGroup) getWorkflowPropertyGroup(sParentPath);
824:
825: propGrp.acquireEditWriteLock();
826: try {
827: propGrp.addChild(prop);
828:
829: propGrp.save();
830: } finally {
831: propGrp.releaseEditWriteLock();
832: }
833:
834: prop.changeStatus(Status.APPROVED);
835:
836: ChildObjectPropertyInstance newPropInst = new ChildObjectPropertyInstance(
837: m_dsi, wrkflwRelnProp);
838:
839: newPropInst.addValue(prop);
840:
841: prof.addPropertyInstance(newPropInst);
842:
843: valGrp = (ValueGroup) valGrp.save();
844:
845: valGrp.changeStatus(Status.APPROVED);
846: }
847: }
848:
849: }
850: }
851: }
852:
853: /**
854: * @param sParentPath
855: * @return
856: */
857: private PropertyGroup getWorkflowPropertyGroup(String sParentPath)
858: throws HarmoniseFactoryException, EditException,
859: InvalidChildException, PopulateException,
860: InvalidNameException {
861: // first look for wrkflow prop group
862: PropertyGroup propGrp = (PropertyGroup) HarmoniseObjectFactory
863: .instantiateHarmoniseObject(m_dsi,
864: WorkflowPropertyGroup.class.getName(),
865: sParentPath);
866:
867: //if it's not a wrkflow prop group it may be a normal prop group
868: if (propGrp == null) {
869: propGrp = (PropertyGroup) HarmoniseObjectFactory
870: .instantiateHarmoniseObject(m_dsi,
871: PropertyGroup.class.getName(), sParentPath);
872: }
873:
874: //doesn't exist so create a new one
875: if (propGrp == null) {
876: int nIndex = sParentPath
877: .lastIndexOf(AbstractParentObject.separator);
878:
879: if (nIndex > 0) {
880: PropertyGroup parentGrp = getWorkflowPropertyGroup(sParentPath
881: .substring(0, nIndex - 1));
882: String sName = HarmoniseNameResolver
883: .getLastSegment(sParentPath);
884: propGrp = new WorkflowPropertyGroup(m_dsi);
885: propGrp.setName(sName);
886: propGrp.save();
887: parentGrp.acquireEditWriteLock();
888: try {
889: parentGrp.addChild(propGrp);
890: parentGrp.save();
891: } finally {
892: parentGrp.releaseEditWriteLock();
893: }
894:
895: propGrp.changeStatus(Status.APPROVED);
896: }
897:
898: }
899: return propGrp;
900: }
901:
902: /**
903: * @param sPath
904: * @return
905: */
906: private ValueGroup getWorkflowValueGroup(String sPath)
907: throws HarmoniseFactoryException, EditException,
908: InvalidChildException, PopulateException,
909: InvalidNameException {
910: // first look for wrkflow prop group
911: ValueGroup valGrp = (ValueGroup) HarmoniseObjectFactory
912: .instantiateHarmoniseObject(m_dsi,
913: WorkflowStageValueGroup.class.getName(), sPath);
914:
915: //if it's not a wrkflow prop group it may be a normal prop group
916: if (valGrp == null) {
917: valGrp = (ValueGroup) HarmoniseObjectFactory
918: .instantiateHarmoniseObject(m_dsi, ValueGroup.class
919: .getName(), sPath);
920: }
921:
922: //doesn't exist so create a new one
923: if (valGrp == null) {
924: int nIndex = sPath
925: .lastIndexOf(AbstractParentObject.separator);
926:
927: if (nIndex > 0) {
928: ValueGroup parentGrp = getWorkflowValueGroup(sPath
929: .substring(0, nIndex));
930: String sName = HarmoniseNameResolver
931: .getLastSegment(sPath);
932: valGrp = new WorkflowStageValueGroup(m_dsi);
933: valGrp.setName(sName);
934: valGrp.save();
935: parentGrp.acquireEditWriteLock();
936: try {
937: parentGrp.addChild(valGrp);
938: parentGrp.save();
939: } finally {
940: parentGrp.releaseEditWriteLock();
941: }
942:
943: valGrp.changeStatus(Status.APPROVED);
944: }
945:
946: }
947: return valGrp;
948: }
949:
950: }
|