http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/DebuggerListener.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/DebuggerListener.java b/src/main/java/freemarker/debug/DebuggerListener.java deleted file mode 100644 index 28b1e25..0000000 --- a/src/main/java/freemarker/debug/DebuggerListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug; - -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.util.EventListener; - -/** - * An interface for components that wish to receive debugging events. - */ -public interface DebuggerListener extends Remote, EventListener { - /** - * Called whenever an environment gets suspended (ie hits a breakpoint). - * @param e the event object - */ - public void environmentSuspended(EnvironmentSuspendedEvent e) - throws RemoteException; -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/EnvironmentSuspendedEvent.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/EnvironmentSuspendedEvent.java b/src/main/java/freemarker/debug/EnvironmentSuspendedEvent.java deleted file mode 100644 index 916e011..0000000 --- a/src/main/java/freemarker/debug/EnvironmentSuspendedEvent.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug; - -import java.util.EventObject; - -/** - * Event describing a suspension of an environment (ie because it hit a - * breakpoint). - */ -public class EnvironmentSuspendedEvent extends EventObject { - private static final long serialVersionUID = 1L; - - private final String name; - private final int line; - private final DebuggedEnvironment env; - - public EnvironmentSuspendedEvent(Object source, String templateName, int line, DebuggedEnvironment env) { - super(source); - this.name = templateName; - this.line = line; - this.env = env; - } - - /** - * The name of the template where the execution of the environment - * was suspended - * @return String the template name - */ - public String getName() { - return this.name; - } - - /** - * The line number in the template where the execution of the environment - * was suspended. - * @return int the line number - */ - public int getLine() { - return line; - } - - /** - * The environment that was suspended - * @return DebuggedEnvironment - */ - public DebuggedEnvironment getEnvironment() { - return env; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/DebuggerServer.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/DebuggerServer.java b/src/main/java/freemarker/debug/impl/DebuggerServer.java deleted file mode 100644 index fa7a2ad..0000000 --- a/src/main/java/freemarker/debug/impl/DebuggerServer.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.io.UnsupportedEncodingException; -import java.net.ServerSocket; -import java.net.Socket; -import java.security.MessageDigest; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Random; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import freemarker.debug.Debugger; -import freemarker.template.utility.SecurityUtilities; -import freemarker.template.utility.UndeclaredThrowableException; - -/** - */ -class DebuggerServer { - private static final Logger LOG = LoggerFactory.getLogger("freemarker.debug.server"); - // TODO: Eventually replace with Yarrow - // TODO: Can be extremely slow (on Linux, not enough entropy) - private static final Random R = new SecureRandom(); - - private final byte[] password; - private final int port; - private final Serializable debuggerStub; - private boolean stop = false; - private ServerSocket serverSocket; - - public DebuggerServer(Serializable debuggerStub) { - port = SecurityUtilities.getSystemProperty("freemarker.debug.port", Debugger.DEFAULT_PORT).intValue(); - try { - password = SecurityUtilities.getSystemProperty("freemarker.debug.password", "").getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new UndeclaredThrowableException(e); - } - this.debuggerStub = debuggerStub; - } - - public void start() { - new Thread(new Runnable() - { - @Override - public void run() { - startInternal(); - } - }, "FreeMarker Debugger Server Acceptor").start(); - } - - private void startInternal() { - try { - serverSocket = new ServerSocket(port); - while (!stop) { - Socket s = serverSocket.accept(); - new Thread(new DebuggerAuthProtocol(s)).start(); - } - } catch (IOException e) { - LOG.error("Debugger server shut down.", e); - } - } - - private class DebuggerAuthProtocol implements Runnable { - private final Socket s; - - DebuggerAuthProtocol(Socket s) { - this.s = s; - } - - @Override - public void run() { - try { - ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream()); - ObjectInputStream in = new ObjectInputStream(s.getInputStream()); - byte[] challenge = new byte[512]; - R.nextBytes(challenge); - out.writeInt(220); // protocol version - out.writeObject(challenge); - MessageDigest md = MessageDigest.getInstance("SHA"); - md.update(password); - md.update(challenge); - byte[] response = (byte[]) in.readObject(); - if (Arrays.equals(response, md.digest())) { - out.writeObject(debuggerStub); - } else { - out.writeObject(null); - } - } catch (Exception e) { - LOG.warn("Connection to {} abruply broke", s.getInetAddress().getHostAddress(), e); - } - } - - } - - public void stop() { - this.stop = true; - if (serverSocket != null) { - try { - serverSocket.close(); - } catch (IOException e) { - LOG.error("Unable to close server socket.", e); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/DebuggerService.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/DebuggerService.java b/src/main/java/freemarker/debug/impl/DebuggerService.java deleted file mode 100644 index d51d7b1..0000000 --- a/src/main/java/freemarker/debug/impl/DebuggerService.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.rmi.RemoteException; -import java.util.Collections; -import java.util.List; - -import freemarker.core.Environment; -import freemarker.template.Template; -import freemarker.template.utility.SecurityUtilities; - -/** - * This class provides debugging hooks for the core FreeMarker engine. It is - * not usable for anyone outside the FreeMarker core classes. It is public only - * as an implementation detail. - */ -public abstract class DebuggerService { - private static final DebuggerService instance = createInstance(); - - private static DebuggerService createInstance() { - // Creates the appropriate service class. If the debugging is turned - // off, this is a fast no-op service, otherwise it's the real-thing - // RMI service. - return - SecurityUtilities.getSystemProperty("freemarker.debug.password", null) == null - ? (DebuggerService) new NoOpDebuggerService() - : (DebuggerService) new RmiDebuggerService(); - } - - public static List getBreakpoints(String templateName) { - return instance.getBreakpointsSpi(templateName); - } - - abstract List getBreakpointsSpi(String templateName); - - public static void registerTemplate(Template template) { - instance.registerTemplateSpi(template); - } - - abstract void registerTemplateSpi(Template template); - - public static boolean suspendEnvironment(Environment env, String templateName, int line) - throws RemoteException { - return instance.suspendEnvironmentSpi(env, templateName, line); - } - - abstract boolean suspendEnvironmentSpi(Environment env, String templateName, int line) - throws RemoteException; - - abstract void shutdownSpi(); - - public static void shutdown() { - instance.shutdownSpi(); - } - - private static class NoOpDebuggerService extends DebuggerService { - @Override - List getBreakpointsSpi(String templateName) { - return Collections.EMPTY_LIST; - } - - @Override - boolean suspendEnvironmentSpi(Environment env, String templateName, int line) { - throw new UnsupportedOperationException(); - } - - @Override - void registerTemplateSpi(Template template) { - } - - @Override - void shutdownSpi() { - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/RmiDebugModelImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/RmiDebugModelImpl.java b/src/main/java/freemarker/debug/impl/RmiDebugModelImpl.java deleted file mode 100644 index 6bc84d5..0000000 --- a/src/main/java/freemarker/debug/impl/RmiDebugModelImpl.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import freemarker.debug.DebugModel; -import freemarker.template.TemplateBooleanModel; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateDateModel; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateMethodModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateModelIterator; -import freemarker.template.TemplateNumberModel; -import freemarker.template.TemplateScalarModel; -import freemarker.template.TemplateSequenceModel; -import freemarker.template.TemplateTransformModel; - -/** - */ -class RmiDebugModelImpl extends UnicastRemoteObject implements DebugModel { - private static final long serialVersionUID = 1L; - - private final TemplateModel model; - private final int type; - - RmiDebugModelImpl(TemplateModel model, int extraTypes) throws RemoteException { - super(); - this.model = model; - type = calculateType(model) + extraTypes; - } - - private static DebugModel getDebugModel(TemplateModel tm) throws RemoteException { - return (DebugModel) RmiDebuggedEnvironmentImpl.getCachedWrapperFor(tm); - } - public String getAsString() throws TemplateModelException { - return ((TemplateScalarModel) model).getAsString(); - } - - public Number getAsNumber() throws TemplateModelException { - return ((TemplateNumberModel) model).getAsNumber(); - } - - public Date getAsDate() throws TemplateModelException { - return ((TemplateDateModel) model).getAsDate(); - } - - public int getDateType() { - return ((TemplateDateModel) model).getDateType(); - } - - public boolean getAsBoolean() throws TemplateModelException { - return ((TemplateBooleanModel) model).getAsBoolean(); - } - - public int size() throws TemplateModelException { - if (model instanceof TemplateSequenceModel) { - return ((TemplateSequenceModel) model).size(); - } - return ((TemplateHashModelEx) model).size(); - } - - public DebugModel get(int index) throws TemplateModelException, RemoteException { - return getDebugModel(((TemplateSequenceModel) model).get(index)); - } - - public DebugModel[] get(int fromIndex, int toIndex) throws TemplateModelException, RemoteException { - DebugModel[] dm = new DebugModel[toIndex - fromIndex]; - TemplateSequenceModel s = (TemplateSequenceModel) model; - for (int i = fromIndex; i < toIndex; i++) { - dm[i - fromIndex] = getDebugModel(s.get(i)); - } - return dm; - } - - public DebugModel[] getCollection() throws TemplateModelException, RemoteException { - List list = new ArrayList(); - TemplateModelIterator i = ((TemplateCollectionModel) model).iterator(); - while (i.hasNext()) { - list.add(getDebugModel(i.next())); - } - return (DebugModel[]) list.toArray(new DebugModel[list.size()]); - } - - public DebugModel get(String key) throws TemplateModelException, RemoteException { - return getDebugModel(((TemplateHashModel) model).get(key)); - } - - public DebugModel[] get(String[] keys) throws TemplateModelException, RemoteException { - DebugModel[] dm = new DebugModel[keys.length]; - TemplateHashModel h = (TemplateHashModel) model; - for (int i = 0; i < keys.length; i++) { - dm[i] = getDebugModel(h.get(keys[i])); - } - return dm; - } - - public String[] keys() throws TemplateModelException { - TemplateHashModelEx h = (TemplateHashModelEx) model; - List list = new ArrayList(); - TemplateModelIterator i = h.keys().iterator(); - while (i.hasNext()) { - list.add(((TemplateScalarModel) i.next()).getAsString()); - } - return (String[]) list.toArray(new String[list.size()]); - } - - public int getModelTypes() { - return type; - } - - private static int calculateType(TemplateModel model) { - int type = 0; - if (model instanceof TemplateScalarModel) type += TYPE_SCALAR; - if (model instanceof TemplateNumberModel) type += TYPE_NUMBER; - if (model instanceof TemplateDateModel) type += TYPE_DATE; - if (model instanceof TemplateBooleanModel) type += TYPE_BOOLEAN; - if (model instanceof TemplateSequenceModel) type += TYPE_SEQUENCE; - if (model instanceof TemplateCollectionModel) type += TYPE_COLLECTION; - if (model instanceof TemplateHashModelEx) type += TYPE_HASH_EX; - else if (model instanceof TemplateHashModel) type += TYPE_HASH; - if (model instanceof TemplateMethodModelEx) type += TYPE_METHOD_EX; - else if (model instanceof TemplateMethodModel) type += TYPE_METHOD; - if (model instanceof TemplateTransformModel) type += TYPE_TRANSFORM; - return type; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java b/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java deleted file mode 100644 index 815f83b..0000000 --- a/src/main/java/freemarker/debug/impl/RmiDebuggedEnvironmentImpl.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import freemarker.cache.CacheStorage; -import freemarker.cache.SoftCacheStorage; -import freemarker.core.Configurable; -import freemarker.core.Environment; -import freemarker.debug.DebugModel; -import freemarker.debug.DebuggedEnvironment; -import freemarker.template.Configuration; -import freemarker.template.SimpleCollection; -import freemarker.template.SimpleScalar; -import freemarker.template.Template; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.utility.UndeclaredThrowableException; - -/** - */ -class RmiDebuggedEnvironmentImpl -extends - RmiDebugModelImpl -implements - DebuggedEnvironment { - private static final long serialVersionUID = 1L; - - private static final CacheStorage storage = new SoftCacheStorage(new IdentityHashMap()); - private static final Object idLock = new Object(); - private static long nextId = 1; - private static Set remotes = new HashSet(); - - - private boolean stopped = false; - private final long id; - - private RmiDebuggedEnvironmentImpl(Environment env) throws RemoteException { - super(new DebugEnvironmentModel(env), DebugModel.TYPE_ENVIRONMENT); - synchronized (idLock) { - id = nextId++; - } - } - - static synchronized Object getCachedWrapperFor(Object key) - throws RemoteException { - Object value = storage.get(key); - if (value == null) { - if (key instanceof TemplateModel) { - int extraTypes; - if (key instanceof DebugConfigurationModel) { - extraTypes = DebugModel.TYPE_CONFIGURATION; - } else if (key instanceof DebugTemplateModel) { - extraTypes = DebugModel.TYPE_TEMPLATE; - } else { - extraTypes = 0; - } - value = new RmiDebugModelImpl((TemplateModel) key, extraTypes); - } else if (key instanceof Environment) { - value = new RmiDebuggedEnvironmentImpl((Environment) key); - } else if (key instanceof Template) { - value = new DebugTemplateModel((Template) key); - } else if (key instanceof Configuration) { - value = new DebugConfigurationModel((Configuration) key); - } - } - if (value != null) { - storage.put(key, value); - } - if (value instanceof Remote) { - remotes.add(value); - } - return value; - } - - // TODO See in SuppressFBWarnings - @Override - @SuppressFBWarnings(value="NN_NAKED_NOTIFY", justification="Will have to be re-desigend; postponed.") - public void resume() { - synchronized (this) { - notify(); - } - } - - @Override - public void stop() { - stopped = true; - resume(); - } - - @Override - public long getId() { - return id; - } - - boolean isStopped() { - return stopped; - } - - private abstract static class DebugMapModel implements TemplateHashModelEx { - @Override - public int size() { - return keySet().size(); - } - - @Override - public TemplateCollectionModel keys() { - return new SimpleCollection(keySet()); - } - - @Override - public TemplateCollectionModel values() throws TemplateModelException { - Collection keys = keySet(); - List list = new ArrayList(keys.size()); - - for (Iterator it = keys.iterator(); it.hasNext(); ) { - list.add(get((String) it.next())); - } - return new SimpleCollection(list); - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - abstract Collection keySet(); - - static List composeList(Collection c1, Collection c2) { - List list = new ArrayList(c1); - list.addAll(c2); - Collections.sort(list); - return list; - } - } - - private static class DebugConfigurableModel extends DebugMapModel { - static final List KEYS = Arrays.asList(new String[] - { - Configurable.ARITHMETIC_ENGINE_KEY, - Configurable.BOOLEAN_FORMAT_KEY, - Configurable.LOCALE_KEY, - Configurable.NUMBER_FORMAT_KEY, - Configurable.OBJECT_WRAPPER_KEY, - Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY - }); - - final Configurable configurable; - - DebugConfigurableModel(Configurable configurable) { - this.configurable = configurable; - } - - @Override - Collection keySet() { - return KEYS; - } - - @Override - public TemplateModel get(String key) throws TemplateModelException { - String s = configurable.getSetting(key); - return s == null ? null : new SimpleScalar(s); - } - - } - - private static class DebugConfigurationModel extends DebugConfigurableModel { - private static final List KEYS = composeList(DebugConfigurableModel.KEYS, Collections.singleton("sharedVariables")); - - private TemplateModel sharedVariables = new DebugMapModel() - { - @Override - Collection keySet() { - return ((Configuration) configurable).getSharedVariableNames(); - } - - @Override - public TemplateModel get(String key) { - return ((Configuration) configurable).getSharedVariable(key); - } - }; - - DebugConfigurationModel(Configuration config) { - super(config); - } - - @Override - Collection keySet() { - return KEYS; - } - - @Override - public TemplateModel get(String key) throws TemplateModelException { - if ("sharedVariables".equals(key)) { - return sharedVariables; - } else { - return super.get(key); - } - } - } - - private static class DebugTemplateModel extends DebugConfigurableModel { - private static final List KEYS = composeList(DebugConfigurableModel.KEYS, - Arrays.asList(new String[] { - "configuration", - "name", - })); - - private final SimpleScalar name; - - DebugTemplateModel(Template template) { - super(template); - this.name = new SimpleScalar(template.getName()); - } - - @Override - Collection keySet() { - return KEYS; - } - - @Override - public TemplateModel get(String key) throws TemplateModelException { - if ("configuration".equals(key)) { - try { - return (TemplateModel) getCachedWrapperFor(((Template) configurable).getConfiguration()); - } catch (RemoteException e) { - throw new TemplateModelException(e); - } - } - if ("name".equals(key)) { - return name; - } - return super.get(key); - } - } - - private static class DebugEnvironmentModel extends DebugConfigurableModel { - private static final List KEYS = composeList(DebugConfigurableModel.KEYS, - Arrays.asList(new String[] { - "currentNamespace", - "dataModel", - "globalNamespace", - "knownVariables", - "mainNamespace", - "template", - })); - - private TemplateModel knownVariables = new DebugMapModel() - { - @Override - Collection keySet() { - try { - return ((Environment) configurable).getKnownVariableNames(); - } catch (TemplateModelException e) { - throw new UndeclaredThrowableException(e); - } - } - - @Override - public TemplateModel get(String key) throws TemplateModelException { - return ((Environment) configurable).getVariable(key); - } - }; - - DebugEnvironmentModel(Environment env) { - super(env); - } - - @Override - Collection keySet() { - return KEYS; - } - - @Override - public TemplateModel get(String key) throws TemplateModelException { - if ("currentNamespace".equals(key)) { - return ((Environment) configurable).getCurrentNamespace(); - } - if ("dataModel".equals(key)) { - return ((Environment) configurable).getDataModel(); - } - if ("globalNamespace".equals(key)) { - return ((Environment) configurable).getGlobalNamespace(); - } - if ("knownVariables".equals(key)) { - return knownVariables; - } - if ("mainNamespace".equals(key)) { - return ((Environment) configurable).getMainNamespace(); - } - if ("template".equals(key)) { - try { - return (TemplateModel) getCachedWrapperFor(((Environment) configurable).getTemplate()); - } catch (RemoteException e) { - throw new TemplateModelException(e); - } - } - return super.get(key); - } - } - - public static void cleanup() { - for (Iterator i = remotes.iterator(); i.hasNext(); ) { - Object remoteObject = i.next(); - try { - UnicastRemoteObject.unexportObject((Remote) remoteObject, true); - } catch (Exception e) { - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/RmiDebuggerImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggerImpl.java b/src/main/java/freemarker/debug/impl/RmiDebuggerImpl.java deleted file mode 100644 index 61a5e14..0000000 --- a/src/main/java/freemarker/debug/impl/RmiDebuggerImpl.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; -import java.util.Collection; -import java.util.List; - -import freemarker.debug.Breakpoint; -import freemarker.debug.Debugger; -import freemarker.debug.DebuggerListener; - -/** - */ -class RmiDebuggerImpl -extends - UnicastRemoteObject -implements - Debugger { - private static final long serialVersionUID = 1L; - - private final RmiDebuggerService service; - - protected RmiDebuggerImpl(RmiDebuggerService service) throws RemoteException { - this.service = service; - } - - public void addBreakpoint(Breakpoint breakpoint) { - service.addBreakpoint(breakpoint); - } - - public Object addDebuggerListener(DebuggerListener listener) { - return service.addDebuggerListener(listener); - } - - public List getBreakpoints() { - return service.getBreakpointsSpi(); - } - - public List getBreakpoints(String templateName) { - return service.getBreakpointsSpi(templateName); - } - - public Collection getSuspendedEnvironments() { - return service.getSuspendedEnvironments(); - } - - public void removeBreakpoint(Breakpoint breakpoint) { - service.removeBreakpoint(breakpoint); - } - - public void removeDebuggerListener(Object id) { - service.removeDebuggerListener(id); - } - - public void removeBreakpoints() { - service.removeBreakpoints(); - } - - public void removeBreakpoints(String templateName) { - service.removeBreakpoints(templateName); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/RmiDebuggerListenerImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggerListenerImpl.java b/src/main/java/freemarker/debug/impl/RmiDebuggerListenerImpl.java deleted file mode 100644 index da65308..0000000 --- a/src/main/java/freemarker/debug/impl/RmiDebuggerListenerImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.rmi.NoSuchObjectException; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; -import java.rmi.server.Unreferenced; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import freemarker.debug.DebuggerClient; -import freemarker.debug.DebuggerListener; -import freemarker.debug.EnvironmentSuspendedEvent; - -/** - * Used by the {@link DebuggerClient} to create local - */ -public class RmiDebuggerListenerImpl -extends - UnicastRemoteObject -implements - DebuggerListener, Unreferenced { - private static final Logger LOG = LoggerFactory.getLogger( - "freemarker.debug.client"); - - private static final long serialVersionUID = 1L; - - private final DebuggerListener listener; - - @Override - public void unreferenced() { - try { - UnicastRemoteObject.unexportObject(this, false); - } catch (NoSuchObjectException e) { - LOG.warn("Failed to unexport RMI debugger listener", e); - } - } - - public RmiDebuggerListenerImpl(DebuggerListener listener) - throws RemoteException { - this.listener = listener; - } - - @Override - public void environmentSuspended(EnvironmentSuspendedEvent e) - throws RemoteException { - listener.environmentSuspended(e); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/impl/RmiDebuggerService.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/impl/RmiDebuggerService.java b/src/main/java/freemarker/debug/impl/RmiDebuggerService.java deleted file mode 100644 index 25d1b2e..0000000 --- a/src/main/java/freemarker/debug/impl/RmiDebuggerService.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.debug.impl; - -import java.io.Serializable; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.rmi.RemoteException; -import java.rmi.server.RemoteObject; -import java.rmi.server.UnicastRemoteObject; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import freemarker.core.DebugBreak; -import freemarker.core.Environment; -import freemarker.core.TemplateElement; -import freemarker.core._CoreAPI; -import freemarker.debug.Breakpoint; -import freemarker.debug.DebuggerListener; -import freemarker.debug.EnvironmentSuspendedEvent; -import freemarker.template.Template; -import freemarker.template.utility.UndeclaredThrowableException; - -/** - * @version $Id - */ -class RmiDebuggerService -extends - DebuggerService { - private final Map templateDebugInfos = new HashMap(); - private final HashSet suspendedEnvironments = new HashSet(); - private final Map listeners = new HashMap(); - private final ReferenceQueue refQueue = new ReferenceQueue(); - - - private final RmiDebuggerImpl debugger; - private DebuggerServer server; - - RmiDebuggerService() { - try { - debugger = new RmiDebuggerImpl(this); - server = new DebuggerServer((Serializable) RemoteObject.toStub(debugger)); - server.start(); - } catch (RemoteException e) { - e.printStackTrace(); - throw new UndeclaredThrowableException(e); - } - } - - @Override - List getBreakpointsSpi(String templateName) { - synchronized (templateDebugInfos) { - TemplateDebugInfo tdi = findTemplateDebugInfo(templateName); - return tdi == null ? Collections.EMPTY_LIST : tdi.breakpoints; - } - } - - List getBreakpointsSpi() { - List sumlist = new ArrayList(); - synchronized (templateDebugInfos) { - for (Iterator iter = templateDebugInfos.values().iterator(); iter.hasNext(); ) { - sumlist.addAll(((TemplateDebugInfo) iter.next()).breakpoints); - } - } - Collections.sort(sumlist); - return sumlist; - } - - // TODO See in SuppressFBWarnings - @Override - @SuppressFBWarnings(value={ "UW_UNCOND_WAIT", "WA_NOT_IN_LOOP" }, justification="Will have to be re-desigend; postponed.") - boolean suspendEnvironmentSpi(Environment env, String templateName, int line) - throws RemoteException { - RmiDebuggedEnvironmentImpl denv = - (RmiDebuggedEnvironmentImpl) - RmiDebuggedEnvironmentImpl.getCachedWrapperFor(env); - - synchronized (suspendedEnvironments) { - suspendedEnvironments.add(denv); - } - try { - EnvironmentSuspendedEvent breakpointEvent = - new EnvironmentSuspendedEvent(this, templateName, line, denv); - - synchronized (listeners) { - for (Iterator iter = listeners.values().iterator(); iter.hasNext(); ) { - DebuggerListener listener = (DebuggerListener) iter.next(); - listener.environmentSuspended(breakpointEvent); - } - } - synchronized (denv) { - try { - denv.wait(); - } catch (InterruptedException e) { - ;// Intentionally ignored - } - } - return denv.isStopped(); - } finally { - synchronized (suspendedEnvironments) { - suspendedEnvironments.remove(denv); - } - } - } - - @Override - void registerTemplateSpi(Template template) { - String templateName = template.getName(); - synchronized (templateDebugInfos) { - TemplateDebugInfo tdi = createTemplateDebugInfo(templateName); - tdi.templates.add(new TemplateReference(templateName, template, refQueue)); - // Inject already defined breakpoints into the template - for (Iterator iter = tdi.breakpoints.iterator(); iter.hasNext(); ) { - Breakpoint breakpoint = (Breakpoint) iter.next(); - insertDebugBreak(template, breakpoint); - } - } - } - - Collection getSuspendedEnvironments() { - return (Collection) suspendedEnvironments.clone(); - } - - Object addDebuggerListener(DebuggerListener listener) { - Object id; - synchronized (listeners) { - id = Long.valueOf(System.currentTimeMillis()); - listeners.put(id, listener); - } - return id; - } - - void removeDebuggerListener(Object id) { - synchronized (listeners) { - listeners.remove(id); - } - } - - void addBreakpoint(Breakpoint breakpoint) { - String templateName = breakpoint.getTemplateName(); - synchronized (templateDebugInfos) { - TemplateDebugInfo tdi = createTemplateDebugInfo(templateName); - List breakpoints = tdi.breakpoints; - int pos = Collections.binarySearch(breakpoints, breakpoint); - if (pos < 0) { - // Add to the list of breakpoints - breakpoints.add(-pos - 1, breakpoint); - // Inject the breakpoint into all templates with this name - for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) { - TemplateReference ref = (TemplateReference) iter.next(); - Template t = ref.getTemplate(); - if (t == null) { - iter.remove(); - } else { - insertDebugBreak(t, breakpoint); - } - } - } - } - } - - private static void insertDebugBreak(Template t, Breakpoint breakpoint) { - TemplateElement te = findTemplateElement(t.getRootTreeNode(), breakpoint.getLine()); - if (te == null) { - return; - } - TemplateElement parent = _CoreAPI.getParentElement(te); - DebugBreak db = new DebugBreak(te); - // TODO: Ensure there always is a parent by making sure - // that the root element in the template is always a MixedContent - // Also make sure it doesn't conflict with anyone's code. - parent.setChildAt(parent.getIndex(te), db); - } - - private static TemplateElement findTemplateElement(TemplateElement te, int line) { - if (te.getBeginLine() > line || te.getEndLine() < line) { - return null; - } - // Find the narrowest match - List childMatches = new ArrayList(); - for (Enumeration children = te.children(); children.hasMoreElements(); ) { - TemplateElement child = (TemplateElement) children.nextElement(); - TemplateElement childmatch = findTemplateElement(child, line); - if (childmatch != null) { - childMatches.add(childmatch); - } - } - //find a match that exactly matches the begin/end line - TemplateElement bestMatch = null; - for (int i = 0; i < childMatches.size(); i++) { - TemplateElement e = (TemplateElement) childMatches.get(i); - - if ( bestMatch == null ) { - bestMatch = e; - } - - if ( e.getBeginLine() == line && e.getEndLine() > line ) { - bestMatch = e; - } - - if ( e.getBeginLine() == e.getEndLine() && e.getBeginLine() == line) { - bestMatch = e; - break; - } - } - if ( bestMatch != null) { - return bestMatch; - } - // If no child provides narrower match, return this - return te; - } - - private TemplateDebugInfo findTemplateDebugInfo(String templateName) { - processRefQueue(); - return (TemplateDebugInfo) templateDebugInfos.get(templateName); - } - - private TemplateDebugInfo createTemplateDebugInfo(String templateName) { - TemplateDebugInfo tdi = findTemplateDebugInfo(templateName); - if (tdi == null) { - tdi = new TemplateDebugInfo(); - templateDebugInfos.put(templateName, tdi); - } - return tdi; - } - - void removeBreakpoint(Breakpoint breakpoint) { - String templateName = breakpoint.getTemplateName(); - synchronized (templateDebugInfos) { - TemplateDebugInfo tdi = findTemplateDebugInfo(templateName); - if (tdi != null) { - List breakpoints = tdi.breakpoints; - int pos = Collections.binarySearch(breakpoints, breakpoint); - if (pos >= 0) { - breakpoints.remove(pos); - for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) { - TemplateReference ref = (TemplateReference) iter.next(); - Template t = ref.getTemplate(); - if (t == null) { - iter.remove(); - } else { - removeDebugBreak(t, breakpoint); - } - } - } - if (tdi.isEmpty()) { - templateDebugInfos.remove(templateName); - } - } - } - } - - private void removeDebugBreak(Template t, Breakpoint breakpoint) { - TemplateElement te = findTemplateElement(t.getRootTreeNode(), breakpoint.getLine()); - if (te == null) { - return; - } - DebugBreak db = null; - while (te != null) { - if (te instanceof DebugBreak) { - db = (DebugBreak) te; - break; - } - te = _CoreAPI.getParentElement(te); - } - if (db == null) { - return; - } - TemplateElement parent = _CoreAPI.getParentElement(db); - parent.setChildAt(parent.getIndex(db), _CoreAPI.getChildElement(db, 0)); - } - - void removeBreakpoints(String templateName) { - synchronized (templateDebugInfos) { - TemplateDebugInfo tdi = findTemplateDebugInfo(templateName); - if (tdi != null) { - removeBreakpoints(tdi); - if (tdi.isEmpty()) { - templateDebugInfos.remove(templateName); - } - } - } - } - - void removeBreakpoints() { - synchronized (templateDebugInfos) { - for (Iterator iter = templateDebugInfos.values().iterator(); iter.hasNext(); ) { - TemplateDebugInfo tdi = (TemplateDebugInfo) iter.next(); - removeBreakpoints(tdi); - if (tdi.isEmpty()) { - iter.remove(); - } - } - } - } - - private void removeBreakpoints(TemplateDebugInfo tdi) { - tdi.breakpoints.clear(); - for (Iterator iter = tdi.templates.iterator(); iter.hasNext(); ) { - TemplateReference ref = (TemplateReference) iter.next(); - Template t = ref.getTemplate(); - if (t == null) { - iter.remove(); - } else { - removeDebugBreaks(t.getRootTreeNode()); - } - } - } - - private void removeDebugBreaks(TemplateElement te) { - int count = te.getChildCount(); - for (int i = 0; i < count; ++i) { - TemplateElement child = _CoreAPI.getChildElement(te, i); - while (child instanceof DebugBreak) { - TemplateElement dbchild = _CoreAPI.getChildElement(child, 0); - te.setChildAt(i, dbchild); - child = dbchild; - } - removeDebugBreaks(child); - } - } - - private static final class TemplateDebugInfo { - final List templates = new ArrayList(); - final List breakpoints = new ArrayList(); - - boolean isEmpty() { - return templates.isEmpty() && breakpoints.isEmpty(); - } - } - - private static final class TemplateReference extends WeakReference { - final String templateName; - - TemplateReference(String templateName, Template template, ReferenceQueue queue) { - super(template, queue); - this.templateName = templateName; - } - - Template getTemplate() { - return (Template) get(); - } - } - - private void processRefQueue() { - for (; ; ) { - TemplateReference ref = (TemplateReference) refQueue.poll(); - if (ref == null) { - break; - } - TemplateDebugInfo tdi = findTemplateDebugInfo(ref.templateName); - if (tdi != null) { - tdi.templates.remove(ref); - if (tdi.isEmpty()) { - templateDebugInfos.remove(ref.templateName); - } - } - } - } - - @Override - void shutdownSpi() { - server.stop(); - try { - UnicastRemoteObject.unexportObject(this.debugger, true); - } catch (Exception e) { - } - - RmiDebuggedEnvironmentImpl.cleanup(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/debug/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/debug/package.html b/src/main/java/freemarker/debug/package.html deleted file mode 100644 index bc8bb81..0000000 --- a/src/main/java/freemarker/debug/package.html +++ /dev/null @@ -1,27 +0,0 @@ -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. ---> -<html> -<head> -</head> -<body bgcolor="white"> -<p>Debugging API; experimental status, might change! -This is to support debugging in IDE-s. If you are working on a client for this, -don't hesitate to contact us!</p> -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/ext/beans/APIModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/ext/beans/APIModel.java b/src/main/java/freemarker/ext/beans/APIModel.java deleted file mode 100644 index 83c4121..0000000 --- a/src/main/java/freemarker/ext/beans/APIModel.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package freemarker.ext.beans; - -/** - * Exposes the Java API (and properties) of an object. - * - * <p> - * Notes: - * <ul> - * <li>The exposing level is inherited from the {@link BeansWrapper}</li> - * <li>But methods will always shadow properties and fields with identical name, regardless of {@link BeansWrapper} - * settings</li> - * </ul> - * - * @since 2.3.22 - */ -final class APIModel extends BeanModel { - - APIModel(Object object, BeansWrapper wrapper) { - super(object, wrapper, false); - } - - protected boolean isMethodsShadowItems() { - return true; - } - -}
