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: package org.apache.lenya.cms.cocoon.source;
018:
019: import java.io.IOException;
020: import java.net.MalformedURLException;
021: import java.util.Map;
022:
023: import org.apache.avalon.framework.configuration.Configuration;
024: import org.apache.avalon.framework.configuration.DefaultConfiguration;
025: import org.apache.avalon.framework.context.Context;
026: import org.apache.avalon.framework.context.ContextException;
027: import org.apache.avalon.framework.context.Contextualizable;
028: import org.apache.avalon.framework.logger.AbstractLogEnabled;
029: import org.apache.avalon.framework.service.ServiceException;
030: import org.apache.avalon.framework.service.ServiceManager;
031: import org.apache.avalon.framework.service.Serviceable;
032: import org.apache.avalon.framework.thread.ThreadSafe;
033: import org.apache.cocoon.components.ContextHelper;
034: import org.apache.cocoon.components.flow.FlowHelper;
035: import org.apache.cocoon.components.modules.input.JXPathHelper;
036: import org.apache.cocoon.components.modules.input.JXPathHelperConfiguration;
037: import org.apache.cocoon.environment.ObjectModelHelper;
038: import org.apache.cocoon.environment.Request;
039: import org.apache.excalibur.source.Source;
040: import org.apache.excalibur.source.SourceException;
041: import org.apache.excalibur.source.SourceFactory;
042: import org.apache.lenya.cms.publication.Publication;
043: import org.apache.lenya.cms.repository.RepositoryException;
044: import org.apache.lenya.cms.repository.RepositoryUtil;
045: import org.apache.lenya.cms.repository.Session;
046: import org.apache.lenya.util.Query;
047:
048: /**
049: * A factory for the "lenya" scheme (virtual protocol), which is used to resolve any src="lenya:..."
050: * attributes in sitemaps. This implementation constructs the path to the source document from the
051: * page envelope and delegates any further resolving to the "context" source resolver of Cocoon.
052: *
053: * @version $Id: LenyaSourceFactory.java 533723 2007-04-30 12:34:26Z andreas $
054: */
055: public class LenyaSourceFactory extends AbstractLogEnabled implements
056: SourceFactory, ThreadSafe, Contextualizable, Serviceable {
057:
058: protected static final String SCHEME = "lenya:";
059:
060: /** fallback if no configuration is available */
061: protected static final String DEFAULT_DELEGATION_SCHEME = "context:";
062: protected static final String DEFAULT_DELEGATION_PREFIX = "/"
063: + Publication.PUBLICATION_PREFIX_URI;
064:
065: private Context context;
066: private ServiceManager manager;
067:
068: /**
069: * Used for resolving the object model.
070: * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
071: */
072: public void contextualize(Context _context) throws ContextException {
073: this .context = _context;
074: }
075:
076: /**
077: * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
078: */
079: public void service(ServiceManager _manager)
080: throws ServiceException {
081: this .manager = _manager;
082: }
083:
084: /**
085: * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
086: */
087: public Source getSource(final String location, final Map parameters)
088: throws MalformedURLException, IOException, SourceException {
089:
090: String sessionName = null;
091:
092: String[] uriAndQuery = location.split("\\?");
093: if (uriAndQuery.length > 1) {
094: Query query = new Query(uriAndQuery[1]);
095: sessionName = query.getValue("session");
096: }
097:
098: Session session;
099: try {
100: session = getSession(sessionName);
101: } catch (RepositoryException e) {
102: throw new RuntimeException(e);
103: }
104:
105: if (getLogger().isDebugEnabled()) {
106: getLogger().debug(
107: "Creating repository source for URI [" + location
108: + "]");
109: }
110:
111: return new RepositorySource(this .manager, location, session,
112: getLogger());
113:
114: }
115:
116: protected Session getSession(String sessionName)
117: throws RepositoryException {
118: Map objectModel = ContextHelper.getObjectModel(this .context);
119: Session session;
120: if (sessionName == null) {
121: Request request = ObjectModelHelper.getRequest(objectModel);
122: session = RepositoryUtil.getSession(this .manager, request);
123: } else if (sessionName.equals("usecase")) {
124: session = getUsecaseSession(objectModel);
125: } else {
126: throw new RepositoryException("Invalid session: ["
127: + sessionName + "]");
128: }
129:
130: return session;
131: }
132:
133: protected Session getUsecaseSession(Map objectModel)
134: throws RepositoryException {
135: try {
136: Configuration config = new DefaultConfiguration("foo");
137: JXPathHelperConfiguration helperConfig = JXPathHelper
138: .setup(config);
139: Object contextObject = FlowHelper
140: .getContextObject(objectModel);
141: return (Session) JXPathHelper.getAttribute(
142: "usecase/session", config, helperConfig,
143: contextObject);
144: } catch (Exception e) {
145: throw new RepositoryException(e);
146: }
147: }
148:
149: /**
150: * Does nothing because the delegated factory does this.
151: * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
152: */
153: public void release(Source source) {
154: // do nothing
155: }
156: }
|