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.cocoon.forms.generation;
018:
019: import java.io.IOException;
020: import java.util.Locale;
021: import java.util.Map;
022:
023: import org.apache.avalon.framework.context.Context;
024: import org.apache.avalon.framework.context.ContextException;
025: import org.apache.avalon.framework.context.Contextualizable;
026: import org.apache.avalon.framework.parameters.Parameters;
027: import org.apache.avalon.framework.service.ServiceException;
028: import org.apache.avalon.framework.service.ServiceManager;
029: import org.apache.cocoon.ProcessingException;
030: import org.apache.cocoon.components.flow.ContinuationsManager;
031: import org.apache.cocoon.components.flow.InvalidContinuationException;
032: import org.apache.cocoon.components.flow.WebContinuation;
033: import org.apache.cocoon.components.flow.javascript.fom.FOM_Cocoon;
034: import org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptFlowHelper;
035: import org.apache.cocoon.environment.ObjectModelHelper;
036: import org.apache.cocoon.environment.Request;
037: import org.apache.cocoon.environment.SourceResolver;
038: import org.apache.cocoon.forms.FormsConstants;
039: import org.apache.cocoon.forms.datatype.FilterableSelectionList;
040: import org.apache.cocoon.forms.datatype.SelectionList;
041: import org.apache.cocoon.forms.formmodel.Field;
042: import org.apache.cocoon.forms.formmodel.Form;
043: import org.apache.cocoon.generation.ServiceableGenerator;
044: import org.apache.cocoon.sitemap.SitemapParameters;
045: import org.mozilla.javascript.Scriptable;
046: import org.mozilla.javascript.continuations.Continuation;
047: import org.xml.sax.ContentHandler;
048: import org.xml.sax.SAXException;
049:
050: /**
051: * A generator for suggestion lists.
052: *
053: * @since 2.1.8
054: * @version $Id: SuggestionListGenerator.java 449149 2006-09-23 03:58:05Z crossley $
055: */
056: public class SuggestionListGenerator extends ServiceableGenerator
057: implements Contextualizable {
058:
059: private ContinuationsManager contManager;
060: private WebContinuation wk;
061: private SelectionList list;
062: private String filter;
063: private Locale locale;
064: private Context context;
065:
066: public void contextualize(Context ctx) throws ContextException {
067: this .context = ctx;
068: }
069:
070: public void service(ServiceManager manager) throws ServiceException {
071: super .service(manager);
072: this .contManager = (ContinuationsManager) manager
073: .lookup(ContinuationsManager.ROLE);
074: }
075:
076: public void setup(SourceResolver resolver, Map objectModel,
077: String src, Parameters par) throws ProcessingException,
078: SAXException, IOException {
079: super .setup(resolver, objectModel, src, par);
080:
081: Request req = ObjectModelHelper.getRequest(objectModel);
082:
083: String continuationId = par.getParameter("continuation-id", req
084: .getParameter("continuation-id"));
085: String widgetPath = par.getParameter("widget",
086: req.getParameter("widget")).replace('.', '/');
087: this .filter = par.getParameter("filter", req
088: .getParameter("filter"));
089:
090: // The interpreter id is the sitemap's URI
091: String interpreterId = SitemapParameters
092: .getLocation(parameters).getURI();
093: wk = this .contManager.lookupWebContinuation(continuationId,
094: interpreterId);
095: if (wk == null || wk.disposed()) {
096: throw new InvalidContinuationException(
097: "Cannot get continuation for suggestion list");
098: }
099:
100: Form form = (Form) wk.getAttribute("form");
101: if (form == null) {
102: throw new ProcessingException(
103: "No form is attached to the continuation");
104: }
105:
106: this .locale = form.getLocale();
107:
108: Field field = (Field) form.lookupWidget(widgetPath);
109: list = field.getSuggestionList();
110: if (list == null) {
111: throw new ProcessingException(field
112: + " has no suggestion list");
113: }
114: }
115:
116: public void generate() throws IOException, SAXException,
117: ProcessingException {
118: super .contentHandler.startDocument();
119: super .contentHandler.startPrefixMapping(
120: FormsConstants.INSTANCE_PREFIX,
121: FormsConstants.INSTANCE_NS);
122: ContentHandler handler;
123: if (filter == null || filter.length() == 0
124: || list instanceof FilterableSelectionList) {
125: handler = super .contentHandler;
126: } else {
127: handler = new SelectionListFilter(filter,
128: super .contentHandler);
129: }
130:
131: // Restore the JavaScript execution context, if any
132: Scriptable oldScope = null;
133: FOM_Cocoon cocoon = null;
134: if (wk.getContinuation() instanceof Continuation) {
135: oldScope = FOM_JavaScriptFlowHelper
136: .getFOM_FlowScope(objectModel);
137:
138: Continuation k = (Continuation) wk.getContinuation();
139: Scriptable kScope = k.getParentScope();
140: // Register the current scope for scripts indirectly called from this function
141: FOM_JavaScriptFlowHelper.setFOM_FlowScope(objectModel,
142: kScope);
143: cocoon = (FOM_Cocoon) kScope.get("cocoon", kScope);
144: cocoon.pushCallContext(null, null, this .manager,
145: this .context, getLogger(), wk);
146: }
147:
148: try {
149: if (list instanceof FilterableSelectionList) {
150: ((FilterableSelectionList) list).generateSaxFragment(
151: handler, this .locale, filter);
152: } else {
153: list.generateSaxFragment(handler, this .locale);
154: }
155: } finally {
156: if (oldScope != null) {
157: // Restore it
158: FOM_JavaScriptFlowHelper.setFOM_FlowScope(objectModel,
159: oldScope);
160: cocoon.popCallContext();
161: }
162: }
163:
164: super.contentHandler
165: .endPrefixMapping(FormsConstants.INSTANCE_PREFIX);
166: super.contentHandler.endDocument();
167: }
168:
169: }
|