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.linking;
019:
020: import java.net.MalformedURLException;
021:
022: import org.apache.avalon.framework.configuration.Configurable;
023: import org.apache.avalon.framework.configuration.Configuration;
024: import org.apache.avalon.framework.configuration.ConfigurationException;
025: import org.apache.avalon.framework.logger.AbstractLogEnabled;
026: import org.apache.lenya.cms.publication.Area;
027: import org.apache.lenya.cms.publication.Document;
028: import org.apache.lenya.cms.publication.DocumentFactory;
029: import org.apache.lenya.cms.publication.Publication;
030: import org.apache.lenya.cms.publication.PublicationException;
031: import org.apache.lenya.util.Assert;
032:
033: /**
034: * Link resolver implementation.
035: */
036: public class LinkResolverImpl extends AbstractLogEnabled implements
037: LinkResolver, Configurable {
038:
039: /**
040: * The Avalon role.
041: */
042: public static final String ROLE = LinkResolverImpl.class.getName();
043:
044: public LinkTarget resolve(Document currentDoc, String linkUri)
045: throws MalformedURLException {
046:
047: Link link = new Link(linkUri);
048:
049: String language = getValue(link.getLanguage(), currentDoc
050: .getLanguage());
051: String revisionString = getValue(link.getRevision(), null);
052: String area = getValue(link.getArea(), currentDoc.getArea());
053: String pubId = getValue(link.getPubId(), currentDoc
054: .getPublication().getId());
055:
056: String uuid = getValue(link.getUuid(), currentDoc.getUUID());
057: if (uuid.length() == 0) {
058: uuid = currentDoc.getUUID();
059: }
060:
061: return resolve(currentDoc.getFactory(), pubId, area, uuid,
062: language, revisionString);
063: }
064:
065: protected String getValue(String value, String defaultValue) {
066: if (value == null) {
067: return defaultValue;
068: } else {
069: return value;
070: }
071: }
072:
073: private int fallbackMode = MODE_DEFAULT_LANGUAGE;
074:
075: public int getFallbackMode() {
076: return this .fallbackMode;
077: }
078:
079: public void setFallbackMode(int mode) {
080: this .fallbackMode = mode;
081: }
082:
083: protected static final String ELEMENT_FALLBACK = "fallback";
084:
085: public void configure(Configuration config)
086: throws ConfigurationException {
087: Configuration fallbackConfig = config.getChild(
088: ELEMENT_FALLBACK, false);
089: if (fallbackConfig != null) {
090: boolean fallback = config.getValueAsBoolean();
091: if (fallback) {
092: setFallbackMode(MODE_DEFAULT_LANGUAGE);
093: } else {
094: setFallbackMode(MODE_FAIL);
095: }
096: }
097: }
098:
099: public LinkTarget resolve(DocumentFactory factory, String linkUri)
100: throws MalformedURLException {
101:
102: Link link = new Link(linkUri);
103: String language = link.getLanguage();
104: Assert.notNull("language", language);
105: String uuid = link.getUuid();
106: Assert.notNull("uuid", uuid);
107: String area = link.getArea();
108: Assert.notNull("area", area);
109: String pubId = link.getPubId();
110: Assert.notNull("publication ID", pubId);
111:
112: String revisionString = getValue(link.getRevision(), null);
113:
114: return resolve(factory, pubId, area, uuid, language,
115: revisionString);
116: }
117:
118: protected LinkTarget resolve(DocumentFactory factory, String pubId,
119: String area, String uuid, String language,
120: String revisionString) {
121: int revision;
122: if (revisionString == null) {
123: revision = -1;
124: } else {
125: revision = Integer.valueOf(revisionString).intValue();
126: }
127:
128: try {
129: Publication pub = factory.getPublication(pubId);
130: Area areaObj = pub.getArea(area);
131: Document doc;
132: if (areaObj.contains(uuid, language)) {
133: doc = areaObj.getDocument(uuid, language);
134: } else {
135: if (this .fallbackMode == MODE_FAIL) {
136: doc = null;
137: } else if (this .fallbackMode == MODE_DEFAULT_LANGUAGE) {
138: if (areaObj
139: .contains(uuid, pub.getDefaultLanguage())) {
140: doc = factory.get(pub, area, uuid, pub
141: .getDefaultLanguage(), revision);
142: } else {
143: doc = null;
144: }
145: } else {
146: throw new RuntimeException("The fallback mode ["
147: + this .fallbackMode + "] is not supported!");
148: }
149: }
150: if (doc == null) {
151: return new LinkTarget();
152: } else {
153: if (revision > -1) {
154: return new LinkTarget(doc, revision);
155: } else {
156: return new LinkTarget(doc);
157: }
158: }
159: } catch (PublicationException e) {
160: throw new RuntimeException(e);
161: }
162: }
163:
164: }
|