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: package org.openharmonise.vfs.metadata;
020:
021: import java.util.*;
022:
023: import org.openharmonise.commons.xml.namespace.*;
024: import org.openharmonise.vfs.*;
025: import org.openharmonise.vfs.context.*;
026: import org.openharmonise.vfs.metadata.range.*;
027: import org.openharmonise.vfs.metadata.value.*;
028: import org.openharmonise.vfs.servers.ServerList;
029:
030: /**
031: * Properties are cached so that they are not constantly fetched from
032: * the Harmonise server. When a property is requested from the cache and
033: * there is a version identifier is specified it is compared with the
034: * version identifier of the property in the cache. This way updates to
035: * properties will be fetched into the cache even if there is a previous
036: * version held. Properties can be requested either by the path to their
037: * virtual file or by their fully qualified (i.e. namespace and name) name.
038: *
039: * @author Matthew Large
040: * @version $Revision: 1.2 $
041: *
042: */
043: public class PropertyCache implements ContextListener {
044:
045: /**
046: * Instance of the property cache, following the Singleton pattern.
047: */
048: private static PropertyCache m_instance = null;
049:
050: /**
051: * Property lookup.
052: */
053: private ResourceLookup m_properties = new ResourceLookup(11);
054:
055: /**
056: * Property group lookup.
057: */
058: private ResourceLookup m_propertyGroups = new ResourceLookup(11);
059:
060: /**
061: *
062: */
063: private PropertyCache() {
064: super ();
065: ContextHandler.getInstance().addListener(
066: ContextType.CONTEXT_METADATA_DEFINITION_CHANGED, this );
067: this .setup();
068: }
069:
070: private void setup() {
071: Property stringProp = new Property();
072: stringProp.setNamespace(NamespaceType.OHRM.getURI());
073: stringProp.setHREF("/default/harmonise-path");
074: stringProp.setDisplayName("Harmonise Path");
075: stringProp.setName("harmonise-path");
076: stringProp
077: .setSummary("Harmonise path for this resource, used as a unique reference to this resource by site developers.");
078: StringRange longStringRange = new StringRange();
079: longStringRange.setMaxLength(500);
080: stringProp.setRange(longStringRange);
081: this .addProperty(NamespaceType.OHRM.getURI(), "harmonise-path",
082: stringProp);
083:
084: stringProp = new Property();
085: stringProp.setNamespace(NamespaceType.OHRM.getURI());
086: stringProp.setHREF("/default/harmonise-id");
087: stringProp.setDisplayName("Harmonise ID");
088: stringProp.setName("harmonise-id");
089: stringProp
090: .setSummary("Harmonise ID for this resource, used as a unique reference to this resource by site developers.");
091: longStringRange = new StringRange();
092: longStringRange.setMaxLength(500);
093: stringProp.setRange(longStringRange);
094: this .addProperty(NamespaceType.OHRM.getURI(), "harmonise-id",
095: stringProp);
096: }
097:
098: /**
099: * Returns the instance of the property cache. Follows the Singleton
100: * pattern.
101: *
102: * @return The property cache
103: */
104: public static PropertyCache getInstance() {
105: if (m_instance == null) {
106: m_instance = new PropertyCache();
107: }
108: return m_instance;
109: }
110:
111: /**
112: * Loads stored cache information from an XML file.
113: *
114: * @param sFilePath Path to XML file
115: */
116: public void load(String sFilePath) {
117: Property domainProp = new Property();
118: domainProp.setName("domain");
119: domainProp.setNamespace(NamespaceType.DAV.getURI());
120: domainProp.setRange(new DomainRange());
121: domainProp.setHREF("/Domain");
122: String sQName = domainProp.getNamespace() + "#"
123: + domainProp.getName();
124: this .m_properties.put(sQName, domainProp.getHREF(), domainProp);
125:
126: Property rangeProp = new Property();
127: rangeProp.setName("range");
128: rangeProp.setNamespace(NamespaceType.DAV.getURI());
129: rangeProp.setRange(new RangeRange());
130: rangeProp.setHREF("/Range");
131: sQName = rangeProp.getNamespace() + "#" + rangeProp.getName();
132: this .m_properties.put(sQName, rangeProp.getHREF(), rangeProp);
133:
134: }
135:
136: public void addProperty(String sNamespace, String sName,
137: Property prop) {
138: this .m_properties.put(sNamespace + "#" + sName, null, prop);
139: }
140:
141: /**
142: * Saves cache information to an XML file.
143: *
144: * @param sFilePath Full path to XML file
145: */
146: public void save(String sFilePath) {
147:
148: }
149:
150: /**
151: * Returns a property.
152: *
153: * @param sHREF Full path to virtual file for property
154: * @param sVersion Version identifier of property
155: * @return Property or null if not found
156: */
157: public Property getPropertyByPath(String sHREF, String sVersion) {
158: this .checkDefinition(sHREF, sVersion);
159: return (Property) this .m_properties.getByHREF(sHREF);
160: }
161:
162: /**
163: * Returns a property.
164: *
165: * @param sHREF Full path to virtual file for property.
166: * @return Property or null if not found
167: */
168: public Property getPropertyByPath(String sHREF) {
169: this .checkDefinition(sHREF);
170: return (Property) this .m_properties.getByHREF(sHREF);
171: }
172:
173: /**
174: * Returns a property.
175: *
176: * @param sNamespace Namespace of property
177: * @param sName Name of property
178: * @param sVersion Version identifier of property
179: * @return Property or null if not found
180: */
181: public Property getPropertyByName(String sNamespace, String sName,
182: String sVersion) {
183: String sQName = sNamespace.trim() + "#" + sName.trim();
184: String sHref = this .m_properties.getHref(sQName);
185: if (sHref != null) {
186: this .checkDefinition(sHref, sVersion);
187: }
188: Property prop = (Property) this .m_properties.getByQName(sQName);
189: if (prop == null) {
190: prop = new Property(sNamespace, sName, "/default");
191: }
192: return prop;
193: }
194:
195: /**
196: * Returns a property.
197: *
198: * @param sNamespace Namespace of property
199: * @param sName Name of property
200: * @return Property or null if not found
201: */
202: public Property getPropertyByName(String sNamespace, String sName) {
203: String sQName = sNamespace.trim() + "#" + sName.trim();
204: String sHref = this .m_properties.getHref(sQName);
205: if (sHref != null) {
206: this .checkDefinition(sHref);
207: }
208: Property prop = (Property) this .m_properties.getByQName(sQName);
209: if (prop == null) {
210: prop = new Property(sNamespace, sName, "/default");
211: }
212: return prop;
213: }
214:
215: /**
216: * Checks if the currently cached property is valid. If it is not
217: * valid a new version is fetched.
218: *
219: * @param sHREF Full path to virtual file for property
220: */
221: private void checkDefinition(String sHREF) {
222: this .checkDefinition(sHREF, null);
223: }
224:
225: /**
226: * Checks if the currently cached property is valid. If it is not
227: * valid a new version is fetched.
228: *
229: * @param sHREF Full path to virtual file for property
230: * @param sVersion Version identifier of property
231: */
232: private void checkDefinition(String sHREF, String sVersion) {
233: if (sHREF
234: .equals("/webdav/Metadata/Properties/MattPropCol/mattRemoveCompoundProp")) {
235: System.out.println("Checking prop");
236: }
237: Property prop = (Property) this .m_properties.getByHREF(sHREF);
238: if (prop != null && sVersion != null
239: && prop.getVersion() != null) {
240: if (!prop.getVersion().equals(sVersion)) {
241: prop = this .getPropertyFromVFS(sHREF);
242: if (prop != null) {
243: this .m_properties.put(prop.getNamespace() + "#"
244: + prop.getName(), sHREF, prop);
245: }
246: }
247: } else if (prop == null) {
248: prop = this .getPropertyFromVFS(sHREF);
249: if (prop != null) {
250: this .m_properties.put(prop.getNamespace() + "#"
251: + prop.getName(), sHREF, prop);
252: }
253: } else {
254: // TODO Don't know what to do here.....???
255: }
256: }
257:
258: /**
259: * Returns a property from the Harmonise server virtual file system.
260: *
261: * @param sHREF Full path to the virtual file for property
262: * @return Property or null if not found
263: */
264: private Property getPropertyFromVFS(String sHREF) {
265: Property prop = null;
266:
267: AbstractVersioningVFS vfs = (AbstractVersioningVFS) ServerList
268: .getInstance().getHarmoniseServer().getVFS();
269:
270: VersionedVirtualFile vfFile = (VersionedVirtualFile) vfs
271: .getPropertyVirtualFile(sHREF);
272:
273: if (vfFile != null) {
274: prop = new Property(NamespaceType.OHRM.getURI(), vfFile
275: .getFileName(), vfFile.getFullPath());
276: prop.setDisplayName(vfFile.getVFS()
277: .getVirtualFileSystemView().getDisplayName(vfFile));
278: prop.setSummary(vfFile.getVFS().getVirtualFileSystemView()
279: .getSummary(vfFile));
280:
281: PropertyInstance range = vfFile.getProperty(
282: NamespaceType.DAV.getURI(), "range");
283: PropertyInstance domain = vfFile.getProperty(
284: NamespaceType.DAV.getURI(), "domain");
285:
286: if (range != null) {
287: List rangeValues = range.getValues();
288: if (rangeValues.size() > 0) {
289: RangeValue rangeValue = (RangeValue) rangeValues
290: .get(0);
291: prop.setRange(rangeValue.getRange());
292: }
293: }
294:
295: if (domain != null) {
296: List domainValues = domain.getValues();
297: Iterator itor = domainValues.iterator();
298: while (itor.hasNext()) {
299: DomainValue domainValue = (DomainValue) itor.next();
300: Domain newDomain = new Domain();
301:
302: newDomain.addPath(domainValue.getPath());
303: newDomain.setResourceType(domainValue
304: .getResourceType());
305: newDomain.setMaxOccurs(domainValue.getMaxOccurs());
306: newDomain.setMinOccurs(domainValue.getMinOccurs());
307: Iterator itor2 = domainValue.getContentTypes()
308: .iterator();
309: while (itor2.hasNext()) {
310: String sContentType = (String) itor2.next();
311: newDomain.addContentType(sContentType);
312: }
313:
314: prop.addDomain(newDomain);
315: }
316: }
317: }
318:
319: return prop;
320: }
321:
322: /**
323: * Returns a property group.
324: *
325: * @param sHREF Full path to virtual file for property group
326: * @return Property group or null if not found
327: */
328: public PropertyGroup getPropertyGroup(String sHREF) {
329: AbstractVirtualFileSystem vfs = (AbstractVirtualFileSystem) ServerList
330: .getInstance().getHarmoniseServer().getVFS();
331:
332: VersionedVirtualFile vfDir = (VersionedVirtualFile) vfs
333: .getVirtualFile(sHREF).getResource();
334: PropertyGroup group = null;
335: if (vfDir != null) {
336: List vfChildren = vfDir.getChildren();
337: group = new PropertyGroup();
338: group.setChildrenHREFs(vfChildren);
339: }
340:
341: return group;
342: }
343:
344: public String toString() {
345: StringBuffer sBuff = new StringBuffer();
346:
347: Iterator itor = this .m_properties.getValues().iterator();
348: while (itor.hasNext()) {
349: sBuff.append(((Property) itor.next()).toString()).append(
350: "\n");
351: }
352:
353: return sBuff.toString();
354: }
355:
356: /* (non-Javadoc)
357: * @see com.simulacramedia.contentmanager.context.ContextListener#contextMessage(com.simulacramedia.contentmanager.context.ContextEvent)
358: */
359: public void contextMessage(ContextEvent ce) {
360: if (ce.getPath() != null) {
361: this.m_properties.removeByHREF(ce.getPath());
362: }
363: }
364:
365: }
|