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.publication;
019:
020: import java.util.Map;
021: import java.util.WeakHashMap;
022:
023: /**
024: * A DocumentLocator describes a document based on its path in the site structure. The actual
025: * document doesn't have to exist.
026: */
027: public class DocumentLocator {
028:
029: private static Map locators = new WeakHashMap();
030:
031: /**
032: * Returns a specific document locator.
033: * @param pubId The publication ID.
034: * @param area The area of the document.
035: * @param path The path of the document in the site structure.
036: * @param language The language of the document.
037: * @return A document locator.
038: */
039: public static DocumentLocator getLocator(String pubId, String area,
040: String path, String language) {
041: String key = DocumentLocator
042: .getKey(pubId, area, path, language);
043: DocumentLocator locator = (DocumentLocator) locators.get(key);
044: if (locator == null) {
045: locator = new DocumentLocator(pubId, area, path, language);
046: locators.put(key, locator);
047: }
048: return locator;
049: }
050:
051: protected static final String getKey(String pubId, String area,
052: String path, String language) {
053: return pubId + ":" + area + ":" + path + ":" + language;
054: }
055:
056: private String pubId;
057: private String area;
058: private String path;
059: private String language;
060:
061: protected DocumentLocator(String pubId, String area, String path,
062: String language) {
063: this .path = path;
064: this .pubId = pubId;
065: this .area = area;
066: this .language = language;
067: }
068:
069: /**
070: * @return The area of the document.
071: */
072: public String getArea() {
073: return area;
074: }
075:
076: /**
077: * @return The language of the document.
078: */
079: public String getLanguage() {
080: return language;
081: }
082:
083: /**
084: * @return The path of the document in the site structure.
085: */
086: public String getPath() {
087: return path;
088: }
089:
090: /**
091: * @return The publication ID.
092: */
093: public String getPublicationId() {
094: return pubId;
095: }
096:
097: /**
098: * Returns a locator with the same publication ID, area, and language, but a different path in
099: * the site structure.
100: * @param path The path.
101: * @return A document locator.
102: */
103: public DocumentLocator getPathVersion(String path) {
104: return DocumentLocator.getLocator(getPublicationId(),
105: getArea(), path, getLanguage());
106: }
107:
108: /**
109: * Returns a descendant of this locator.
110: * @param relativePath The relative path which must not begin with a slash and must not be
111: * empty.
112: * @return A document locator.
113: */
114: public DocumentLocator getDescendant(String relativePath) {
115: if (relativePath.length() == 0) {
116: throw new IllegalArgumentException(
117: "The relative path must not be empty!");
118: }
119: if (relativePath.startsWith("/")) {
120: throw new IllegalArgumentException(
121: "The relative path must not start with a slash!");
122: }
123: return getPathVersion(getPath() + "/" + relativePath);
124: }
125:
126: /**
127: * Returns a child of this locator.
128: * @param step The relative path to the child, it must not contain a slash.
129: * @return A document locator.
130: */
131: public DocumentLocator getChild(String step) {
132: if (step.indexOf("/") > -1) {
133: throw new IllegalArgumentException("The step [" + step
134: + "] must not contain a slash!");
135: }
136: return getDescendant(step);
137: }
138:
139: /**
140: * Returns the parent of this locator.
141: * @return A document locator or <code>null</code> if this is the root locator.
142: */
143: public DocumentLocator getParent() {
144: int lastSlashIndex = getPath().lastIndexOf("/");
145: if (lastSlashIndex > -1) {
146: String parentPath = getPath().substring(0, lastSlashIndex);
147: return getPathVersion(parentPath);
148: } else {
149: return null;
150: }
151: }
152:
153: /**
154: * Returns the parent of this locator.
155: * @param defaultPath The path of the locator to return if this is the root locator.
156: * @return A document locator.
157: */
158: public DocumentLocator getParent(String defaultPath) {
159: DocumentLocator parent = getParent();
160: if (parent != null) {
161: return parent;
162: } else {
163: return getPathVersion(defaultPath);
164: }
165: }
166:
167: /**
168: * Returns a locator with the same publication ID, area, and path, but with a different
169: * language.
170: * @param language The language.
171: * @return A document locator.
172: */
173: public DocumentLocator getLanguageVersion(String language) {
174: return DocumentLocator.getLocator(getPublicationId(),
175: getArea(), getPath(), language);
176: }
177:
178: protected String getKey() {
179: return DocumentLocator.getKey(getPublicationId(), getArea(),
180: getPath(), getLanguage());
181: }
182:
183: public boolean equals(Object obj) {
184: if (!(obj instanceof DocumentLocator)) {
185: return false;
186: }
187: DocumentLocator locator = (DocumentLocator) obj;
188: return locator.getKey().equals(getKey());
189: }
190:
191: public int hashCode() {
192: return getKey().hashCode();
193: }
194:
195: public String toString() {
196: return getKey();
197: }
198:
199: /**
200: * Returns a locator with the same publication ID, path, and language, but with a different
201: * area.
202: * @param area The area.
203: * @return A document locator.
204: */
205: public DocumentLocator getAreaVersion(String area) {
206: return DocumentLocator.getLocator(getPublicationId(), area,
207: getPath(), getLanguage());
208: }
209:
210: }
|