001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.js.rhino;
019:
020: import java.io.BufferedReader;
021: import java.io.File;
022: import java.io.FileReader;
023:
024: import java.util.logging.Level;
025: import java.util.logging.Logger;
026:
027: import javax.xml.ws.Service;
028:
029: import org.mozilla.javascript.Context;
030: import org.mozilla.javascript.ContextFactory;
031: import org.mozilla.javascript.Script;
032: import org.mozilla.javascript.Scriptable;
033:
034: public class ProviderFactory {
035: public static final String ILLEGAL_SVCMD_MODE = ": unknown ServiceMode: ";
036: public static final String ILLEGAL_SVCMD_TYPE = ": ServiceMode value must be of type string";
037: public static final String NO_SUCH_FILE = ": file does not exist";
038: public static final String NO_PROVIDER = ": file contains no WebServiceProviders";
039:
040: private static final Logger LOG = Logger
041: .getLogger(ProviderFactory.class.getName());
042:
043: private String epAddress;
044: private boolean isBaseAddr;
045:
046: static {
047: ContextFactory.initGlobal(new RhinoContextFactory());
048: }
049:
050: public ProviderFactory(String baseAddr) {
051: epAddress = baseAddr;
052: isBaseAddr = true;
053: }
054:
055: public ProviderFactory() {
056: // complete
057: }
058:
059: public void createAndPublish(File f, String epAddr, boolean isBase)
060: throws Exception {
061: publishImpl(f, epAddr, isBase);
062: }
063:
064: public synchronized void createAndPublish(File f) throws Exception {
065: publishImpl(f, epAddress, isBaseAddr);
066: }
067:
068: private void publishImpl(File f, String epAddr, boolean isBase)
069: throws Exception {
070: if (!f.exists()) {
071: throw new Exception(f.getPath() + NO_SUCH_FILE);
072: }
073: boolean isE4X = f.getName().endsWith(".jsx");
074: BufferedReader bufrd = new BufferedReader(new FileReader(f));
075: String line = null;
076: StringBuffer sb = new StringBuffer();
077: for (;;) {
078: line = bufrd.readLine();
079: if (line == null) {
080: break;
081: }
082: sb.append(line).append("\n");
083: }
084: String scriptStr = sb.toString();
085:
086: Context cx = Context.enter();
087: boolean providerFound = false;
088: try {
089: Scriptable scriptScope = cx.initStandardObjects(null, true);
090: Object[] ids = compileScript(cx, scriptStr, scriptScope, f);
091: if (ids.length > 0) {
092: Service.Mode mode = Service.Mode.PAYLOAD;
093: for (Object idObj : ids) {
094: if (!(idObj instanceof String)) {
095: continue;
096: }
097: String id = (String) idObj;
098: if (!id.startsWith("WebServiceProvider")) {
099: continue;
100: }
101: Object obj = scriptScope.get(id, scriptScope);
102: if (!(obj instanceof Scriptable)) {
103: continue;
104: }
105: Scriptable wspVar = (Scriptable) obj;
106: providerFound = true;
107: obj = wspVar.get("ServiceMode", wspVar);
108: if (obj != Scriptable.NOT_FOUND) {
109: if (obj instanceof String) {
110: String value = (String) obj;
111: if ("PAYLOAD".equalsIgnoreCase(value)) {
112: mode = Service.Mode.PAYLOAD;
113: } else if ("MESSAGE"
114: .equalsIgnoreCase(value)) {
115: mode = Service.Mode.MESSAGE;
116: } else {
117: throw new Exception(f.getPath()
118: + ILLEGAL_SVCMD_MODE + value);
119: }
120: } else {
121: throw new Exception(f.getPath()
122: + ILLEGAL_SVCMD_TYPE);
123: }
124: }
125: AbstractDOMProvider provider = createProvider(mode,
126: scriptScope, wspVar, epAddr, isBase, isE4X);
127: try {
128: provider.publish();
129: } catch (AbstractDOMProvider.JSDOMProviderException ex) {
130: StringBuffer msg = new StringBuffer(f.getPath());
131: msg.append(": ").append(ex.getMessage());
132: throw new Exception(msg.toString());
133: }
134: }
135: }
136: } finally {
137: Context.exit();
138: }
139: if (!providerFound) {
140: throw new Exception(f.getPath() + NO_PROVIDER);
141: }
142: }
143:
144: protected AbstractDOMProvider createProvider(Service.Mode mode,
145: Scriptable scope, Scriptable wsp, String epAddr,
146: boolean isBase, boolean e4x) throws Exception {
147: if (LOG.isLoggable(Level.FINE)) {
148: String modestr = (mode == Service.Mode.PAYLOAD) ? "payload"
149: : "message";
150: String type = e4x ? "E4X" : "JavaScript";
151: String base = isBase ? "base " : "";
152: StringBuffer msg = new StringBuffer("creating a ");
153: msg.append(modestr).append(" ").append(type).append(
154: " provider for ").append(base).append("address ")
155: .append(epAddr);
156: LOG.log(Level.FINE, msg.toString());
157: }
158: AbstractDOMProvider provider = null;
159: if (mode == Service.Mode.PAYLOAD) {
160: provider = new DOMPayloadProvider(scope, wsp, epAddr,
161: isBase, e4x);
162: } else if (mode == Service.Mode.MESSAGE) {
163: provider = new DOMMessageProvider(scope, wsp, epAddr,
164: isBase, e4x);
165: }
166: return provider;
167: }
168:
169: private Object[] compileScript(Context cx, String scriptStr,
170: Scriptable scriptScope, File f) {
171: int opt = cx.getOptimizationLevel();
172: cx.setOptimizationLevel(-1);
173: Script script = cx.compileString(scriptStr, f.getName(), 1,
174: null);
175: script.exec(cx, scriptScope);
176: Object[] ids = scriptScope.getIds();
177: cx.setOptimizationLevel(opt);
178: script = cx.compileString(scriptStr, f.getName(), 1, null);
179: script.exec(cx, scriptScope);
180: return ids;
181: }
182:
183: static class RhinoContextFactory extends ContextFactory {
184: public boolean hasFeature(Context cx, int feature) {
185: if (feature == Context.FEATURE_DYNAMIC_SCOPE) {
186: return true;
187: }
188: return super.hasFeature(cx, feature);
189: }
190: }
191: }
|