001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.lenya.cms.repository;
019:
020: import java.util.Arrays;
021: import java.util.HashSet;
022: import java.util.Set;
023:
024: import org.apache.avalon.framework.logger.AbstractLogEnabled;
025: import org.apache.avalon.framework.service.ServiceManager;
026: import org.apache.lenya.cms.metadata.Element;
027: import org.apache.lenya.cms.metadata.ElementSet;
028: import org.apache.lenya.cms.metadata.MetaData;
029: import org.apache.lenya.cms.metadata.MetaDataException;
030: import org.apache.lenya.cms.metadata.MetaDataRegistry;
031:
032: /**
033: * Source-node-based meta data.
034: */
035: public class SourceNodeMetaData extends AbstractLogEnabled implements
036: MetaData {
037:
038: private String namespaceUri;
039: private ServiceManager manager;
040: private SourceNodeMetaDataHandler handler;
041:
042: /**
043: * Ctor.
044: * @param namespaceUri The namespace URI.
045: * @param handler The meta data handler.
046: * @param manager The service manager.
047: */
048: public SourceNodeMetaData(String namespaceUri,
049: SourceNodeMetaDataHandler handler, ServiceManager manager) {
050: this .namespaceUri = namespaceUri;
051: this .handler = handler;
052: this .manager = manager;
053: }
054:
055: protected String getNamespaceUri() {
056: return this .namespaceUri;
057: }
058:
059: protected SourceNodeMetaDataHandler getHandler() {
060: return this .handler;
061: }
062:
063: private ElementSet elementSet;
064:
065: public ElementSet getElementSet() {
066: if (this .elementSet == null) {
067: try {
068: MetaDataRegistry registry = (MetaDataRegistry) this .manager
069: .lookup(MetaDataRegistry.ROLE);
070: this .elementSet = registry
071: .getElementSet(this .namespaceUri);
072: } catch (Exception e) {
073: throw new RuntimeException(e);
074: }
075:
076: }
077: return this .elementSet;
078: }
079:
080: public String[] getValues(String key) throws MetaDataException {
081: String[] values = getHandler()
082: .getValues(this .namespaceUri, key);
083: if (values.length == 0) {
084: checkKey(key);
085: }
086: return values;
087: }
088:
089: public String getFirstValue(String key) throws MetaDataException {
090: String[] values = getValues(key);
091: if (values.length == 0) {
092: checkKey(key);
093: return null;
094: } else {
095: return values[0];
096: }
097: }
098:
099: /**
100: * Cache for better performance.
101: */
102: private Set availableKeys;
103:
104: protected Set availableKeys() {
105: if (this .availableKeys == null) {
106: this .availableKeys = new HashSet(Arrays
107: .asList(getAvailableKeys()));
108: }
109: return this .availableKeys;
110: }
111:
112: public String[] getAvailableKeys() {
113: Element[] elements;
114: elements = getElementSet().getElements();
115: String[] keys = new String[elements.length];
116: for (int i = 0; i < elements.length; i++) {
117: keys[i] = elements[i].getName();
118: }
119: return keys;
120: }
121:
122: protected void checkKey(String key) throws MetaDataException {
123: if (!isValidAttribute(key)) {
124: throw new MetaDataException("The meta data element set ["
125: + getElementSet().getNamespaceUri()
126: + "] does not support the key [" + key + "]!");
127: }
128: }
129:
130: public void setValue(String key, String value)
131: throws MetaDataException {
132: checkKey(key);
133: if (value == null) {
134: throw new MetaDataException("The value for key [" + key
135: + "] must not be null.");
136: }
137: getHandler().setValue(this .namespaceUri, key, value);
138: }
139:
140: public void addValue(String key, String value)
141: throws MetaDataException {
142: checkKey(key);
143: if (!getElementSet().getElement(key).isMultiple()
144: && getValues(key).length > 0) {
145: throw new MetaDataException("The element [" + key
146: + "] doesn't support multiple values!");
147: }
148: getHandler().addValue(this .namespaceUri, key, value);
149: }
150:
151: public void replaceBy(MetaData other) throws MetaDataException {
152: Element[] elements = getElementSet().getElements();
153: for (int i = 0; i < elements.length; i++) {
154: if (elements[i].getActionOnCopy() == Element.ONCOPY_COPY) {
155: replaceBy(other, elements[i]);
156: } else if (elements[i].getActionOnCopy() == Element.ONCOPY_DELETE) {
157: String key = elements[i].getName();
158: removeAllValues(key);
159: }
160: }
161: }
162:
163: protected void replaceBy(MetaData other, Element element)
164: throws MetaDataException {
165: String key = element.getName();
166: removeAllValues(key);
167: String[] values = other.getValues(key);
168: for (int j = 0; j < values.length; j++) {
169: addValue(key, values[j]);
170: }
171: }
172:
173: public void forcedReplaceBy(MetaData other)
174: throws MetaDataException {
175: Element[] elements = getElementSet().getElements();
176: for (int i = 0; i < elements.length; i++) {
177: replaceBy(other, elements[i]);
178: }
179: }
180:
181: public String[] getPossibleKeys() {
182: return getAvailableKeys();
183: }
184:
185: public boolean isValidAttribute(String key) {
186: return availableKeys().contains(key);
187: }
188:
189: public long getLastModified() throws MetaDataException {
190: try {
191: return getHandler().getLastModified();
192: } catch (RepositoryException e) {
193: throw new MetaDataException(e);
194: }
195: }
196:
197: public void removeAllValues(String key) throws MetaDataException {
198: checkKey(key);
199: getHandler().removeAllValues(this.namespaceUri, key);
200: }
201:
202: }
|