001: package org.objectweb.celtix.js.rhino;
002:
003: import java.io.BufferedReader;
004: import java.io.File;
005: import java.io.FileReader;
006:
007: import java.util.logging.Level;
008: import java.util.logging.Logger;
009:
010: import javax.xml.ws.Service;
011:
012: import org.mozilla.javascript.Context;
013: import org.mozilla.javascript.ContextFactory;
014: import org.mozilla.javascript.Script;
015: import org.mozilla.javascript.Scriptable;
016:
017: public class ProviderFactory {
018: public static final String ILLEGAL_SVCMD_MODE = ": unknown ServiceMode: ";
019: public static final String ILLEGAL_SVCMD_TYPE = ": ServiceMode value must be of type string";
020: public static final String NO_SUCH_FILE = ": file does not exist";
021: public static final String NO_PROVIDER = ": file contains no WebServiceProviders";
022:
023: private static final Logger LOG = Logger
024: .getLogger(ProviderFactory.class.getName());
025:
026: private String epAddress;
027: private boolean isBaseAddr;
028:
029: static {
030: ContextFactory.initGlobal(new RhinoContextFactory());
031: }
032:
033: public ProviderFactory(String baseAddr) {
034: epAddress = baseAddr;
035: isBaseAddr = true;
036: }
037:
038: public ProviderFactory() {
039: // complete
040: }
041:
042: public void createAndPublish(File f, String epAddr, boolean isBase)
043: throws Exception {
044: publishImpl(f, epAddr, isBase);
045: }
046:
047: public synchronized void createAndPublish(File f) throws Exception {
048: publishImpl(f, epAddress, isBaseAddr);
049: }
050:
051: private void publishImpl(File f, String epAddr, boolean isBase)
052: throws Exception {
053: if (!f.exists()) {
054: throw new Exception(f.getPath() + NO_SUCH_FILE);
055: }
056: boolean isE4X = f.getName().endsWith(".jsx");
057: BufferedReader bufrd = new BufferedReader(new FileReader(f));
058: String line = null;
059: StringBuffer sb = new StringBuffer();
060: for (;;) {
061: line = bufrd.readLine();
062: if (line == null) {
063: break;
064: }
065: sb.append(line).append("\n");
066: }
067: String scriptStr = sb.toString();
068:
069: Context cx = Context.enter();
070: boolean providerFound = false;
071: try {
072: Scriptable scriptScope = cx.initStandardObjects(null, true);
073: Object[] ids = compileScript(cx, scriptStr, scriptScope, f);
074: if (ids.length > 0) {
075: Service.Mode mode = Service.Mode.PAYLOAD;
076: for (Object idObj : ids) {
077: if (!(idObj instanceof String)) {
078: continue;
079: }
080: String id = (String) idObj;
081: if (!id.startsWith("WebServiceProvider")) {
082: continue;
083: }
084: Object obj = scriptScope.get(id, scriptScope);
085: if (!(obj instanceof Scriptable)) {
086: continue;
087: }
088: Scriptable wspVar = (Scriptable) obj;
089: providerFound = true;
090: obj = wspVar.get("ServiceMode", wspVar);
091: if (obj != Scriptable.NOT_FOUND) {
092: if (obj instanceof String) {
093: String value = (String) obj;
094: if ("PAYLOAD".equalsIgnoreCase(value)) {
095: mode = Service.Mode.PAYLOAD;
096: } else if ("MESSAGE"
097: .equalsIgnoreCase(value)) {
098: mode = Service.Mode.MESSAGE;
099: } else {
100: throw new Exception(f.getPath()
101: + ILLEGAL_SVCMD_MODE + value);
102: }
103: } else {
104: throw new Exception(f.getPath()
105: + ILLEGAL_SVCMD_TYPE);
106: }
107: }
108: AbstractDOMProvider provider = createProvider(mode,
109: scriptScope, wspVar, epAddr, isBase, isE4X);
110: try {
111: provider.publish();
112: } catch (AbstractDOMProvider.JSDOMProviderException ex) {
113: StringBuffer msg = new StringBuffer(f.getPath());
114: msg.append(": ").append(ex.getMessage());
115: throw new Exception(msg.toString());
116: }
117: }
118: }
119: } finally {
120: Context.exit();
121: }
122: if (!providerFound) {
123: throw new Exception(f.getPath() + NO_PROVIDER);
124: }
125: }
126:
127: protected AbstractDOMProvider createProvider(Service.Mode mode,
128: Scriptable scope, Scriptable wsp, String epAddr,
129: boolean isBase, boolean e4x) throws Exception {
130: if (LOG.isLoggable(Level.FINE)) {
131: String modestr = (mode == Service.Mode.PAYLOAD) ? "payload"
132: : "message";
133: String type = e4x ? "E4X" : "JavaScript";
134: String base = isBase ? "base " : "";
135: StringBuffer msg = new StringBuffer("creating a ");
136: msg.append(modestr).append(" ").append(type).append(
137: " provider for ").append(base).append("address ")
138: .append(epAddr);
139: LOG.log(Level.FINE, msg.toString());
140: }
141: AbstractDOMProvider provider = null;
142: if (mode == Service.Mode.PAYLOAD) {
143: provider = new DOMPayloadProvider(scope, wsp, epAddr,
144: isBase, e4x);
145: } else if (mode == Service.Mode.MESSAGE) {
146: provider = new DOMMessageProvider(scope, wsp, epAddr,
147: isBase, e4x);
148: }
149: return provider;
150: }
151:
152: private Object[] compileScript(Context cx, String scriptStr,
153: Scriptable scriptScope, File f) {
154: int opt = cx.getOptimizationLevel();
155: cx.setOptimizationLevel(-1);
156: Script script = cx.compileString(scriptStr, f.getName(), 1,
157: null);
158: script.exec(cx, scriptScope);
159: Object[] ids = scriptScope.getIds();
160: cx.setOptimizationLevel(opt);
161: script = cx.compileString(scriptStr, f.getName(), 1, null);
162: script.exec(cx, scriptScope);
163: return ids;
164: }
165:
166: static class RhinoContextFactory extends ContextFactory {
167: public boolean hasFeature(Context cx, int feature) {
168: if (feature == Context.FEATURE_DYNAMIC_SCOPE) {
169: return true;
170: }
171: return super.hasFeature(cx, feature);
172: }
173: }
174: }
|