summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:11:48 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:11:48 +0000
commitece4fd35da7b7fc76264776f81705e6b5b52d3e0 (patch)
tree962794e2a2b1ab91a02c41e4927a527cade83959 /sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache
parent76e9f96ca7f494088fe3af5a46ad0d153e961008 (diff)
Moving 1.x branches
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835140 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache')
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyException.java133
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyRuntimeException.java134
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/LogLevel.java38
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/MonitorFactory.java35
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/InvalidLevelException.java60
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/JavaLoggingMonitorFactory.java186
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/NullMonitorFactory.java48
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/ResourceLoader.java90
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/GeneratedClassLoader.java45
-rw-r--r--sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/ResourceLoaderImpl.java137
10 files changed, 906 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyException.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyException.java
new file mode 100644
index 0000000000..2bf802520d
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyException.java
@@ -0,0 +1,133 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The root checked exception for the Tuscany runtime.
+ *
+ * @version $Rev: 368822 $ $Date: 2006-01-13 10:54:38 -0800 (Fri, 13 Jan 2006) $
+ */
+public abstract class TuscanyException extends Exception {
+ private static final long serialVersionUID = -7847121698339635268L;
+ private List<String> contextStack;
+ private String identifier;
+
+ /**
+ * Override constructor from Exception.
+ *
+ * @see Exception
+ */
+ public TuscanyException() {
+ super();
+ }
+
+ /**
+ * Override constructor from Exception.
+ *
+ * @param message passed to Exception
+ * @see Exception
+ */
+ public TuscanyException(String message) {
+ super(message);
+ }
+
+ /**
+ * Override constructor from Exception.
+ *
+ * @param message passed to Exception
+ * @param cause passed to Exception
+ * @see Exception
+ */
+ public TuscanyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Override constructor from Exception.
+ *
+ * @param cause passed to Exception
+ * @see Exception
+ */
+ public TuscanyException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns a collection of names representing the context call stack where the error occured.
+ * The top of the stack is the first element in the collection.
+ *
+ * @return a collection of names representing the context call stack
+ */
+ public List<String> returnContextNames() {
+ if (contextStack == null) {
+ contextStack = new ArrayList<String>();
+ }
+ return contextStack;
+ }
+
+ /**
+ * Pushes a context name where an error occured onto the call stack.
+ *
+ * @param name the name of a context to push on the stack
+ */
+ public void addContextName(String name) {
+ if (contextStack == null) {
+ contextStack = new ArrayList<String>();
+ }
+ contextStack.add(name);
+ }
+
+ /**
+ * Returns a string representing additional error information referred to in the error message.
+ *
+ * @return additional error information
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Sets an additional error information referred to in the error message.
+ *
+ * @param identifier additional error information
+ */
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getMessage() {
+ if (identifier == null && contextStack == null) {
+ return super.getMessage();
+ }
+ StringBuilder b = new StringBuilder(256);
+ b.append(super.getMessage());
+
+ if (identifier != null) {
+ b.append(" [").append(identifier).append(']');
+ }
+ if (contextStack != null) {
+ b.append("\nContext stack trace: ");
+ for (int i = contextStack.size() - 1; i >= 0; i--) {
+ b.append('[').append(contextStack.get(i)).append(']');
+ }
+ }
+ return b.toString();
+ }
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyRuntimeException.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyRuntimeException.java
new file mode 100644
index 0000000000..60f2e2287a
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/TuscanyRuntimeException.java
@@ -0,0 +1,134 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The root unchecked exception for the Tuscany runtime.
+ *
+ * @version $Rev: 368822 $ $Date: 2006-01-13 10:54:38 -0800 (Fri, 13 Jan 2006) $
+ */
+
+public abstract class TuscanyRuntimeException extends RuntimeException {
+ private static final long serialVersionUID = -759677431966121786L;
+ private List<String> contextStack;
+ private String identifier;
+
+ /**
+ * Override constructor from RuntimeException.
+ *
+ * @see RuntimeException
+ */
+ public TuscanyRuntimeException() {
+ super();
+ }
+
+ /**
+ * Override constructor from RuntimeException.
+ *
+ * @param message passed to RuntimeException
+ * @see RuntimeException
+ */
+ public TuscanyRuntimeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Override constructor from RuntimeException.
+ *
+ * @param message passed to RuntimeException
+ * @param cause passed to RuntimeException
+ * @see RuntimeException
+ */
+ public TuscanyRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Override constructor from RuntimeException.
+ *
+ * @param cause passed to RuntimeException
+ * @see RuntimeException
+ */
+ public TuscanyRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns a collection of names representing the context call stack where the error occured.
+ * The top of the stack is the first element in the collection.
+ *
+ * @return a collection of names representing the context call stack
+ */
+ public List<String> returnContextNames() {
+ if (contextStack == null) {
+ contextStack = new ArrayList<String>();
+ }
+ return contextStack;
+ }
+
+ /**
+ * Pushes a context name where an error occured onto the call stack.
+ *
+ * @param name the name of a context to push on the stack
+ */
+ public void addContextName(String name) {
+ if (contextStack == null) {
+ contextStack = new ArrayList<String>();
+ }
+ contextStack.add(name);
+ }
+
+ /**
+ * Returns a string representing additional error information referred to in the error message.
+ *
+ * @return additional error information
+ */
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Sets an additional error information referred to in the error message.
+ *
+ * @param identifier additional error information
+ */
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getMessage() {
+ if (identifier == null && contextStack == null) {
+ return super.getMessage();
+ }
+ StringBuilder b = new StringBuilder(256);
+ b.append(super.getMessage());
+
+ if (identifier != null) {
+ b.append(" [").append(identifier).append(']');
+ }
+ if (contextStack != null) {
+ b.append("\nContext stack trace: ");
+ for (int i = contextStack.size() - 1; i >= 0; i--) {
+ b.append('[').append(contextStack.get(i)).append(']');
+ }
+ }
+ return b.toString();
+ }
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/LogLevel.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/LogLevel.java
new file mode 100644
index 0000000000..45134c7556
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/LogLevel.java
@@ -0,0 +1,38 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.monitor;
+
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that can be applied to methods in a monitoring interface
+ * to indicate to logging frameworks the severity of the event.
+ *
+ * @version $Rev$ $Date$
+ */
+@Target({METHOD})
+@Retention(RUNTIME)
+public @interface LogLevel {
+
+ /**
+ * The log level as specified by {@link java.util.logging.Level}.
+ */
+ @SuppressWarnings({"JavaDoc"}) String value();
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/MonitorFactory.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/MonitorFactory.java
new file mode 100644
index 0000000000..aa92092005
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/MonitorFactory.java
@@ -0,0 +1,35 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.monitor;
+
+/**
+ * A MonitorFactory creates implementations of components' monitor interfaces
+ * that interface with a its monitoring scheme. For example, a implementation
+ * may create versions that emit appropriate logging events or which send
+ * notifications to a management API.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface MonitorFactory {
+ /**
+ * Return a monitor for a component's monitor interface.
+ *
+ * @param monitorInterface the component's monitoring interface
+ * @return an implementation of the monitoring interface; will not be null
+ */
+ <T> T getMonitor(Class<T> monitorInterface);
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/InvalidLevelException.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/InvalidLevelException.java
new file mode 100644
index 0000000000..baf4e8b7cc
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/InvalidLevelException.java
@@ -0,0 +1,60 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.monitor.impl;
+
+/**
+ * Exception indicating an invalid log level has been passed.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidLevelException extends IllegalArgumentException {
+ private static final long serialVersionUID = 7767234706427841915L;
+ private final String method;
+ private final String level;
+
+ /**
+ * Constructor specifying the method name and the level affected.
+ *
+ * @param method the name of the method being monitored
+ * @param level the invalid log level value
+ */
+ public InvalidLevelException(String method, String level) {
+ super();
+ this.method = method;
+ this.level = level;
+ }
+
+ /**
+ * Returns the name of the method being monitored.
+ * @return the name of the method being monitored
+ */
+ public String getMethod() {
+ return method;
+ }
+
+ /**
+ * Returns the invalid log level specified.
+ * @return the invalid log level that was specified
+ */
+ public String getLevel() {
+ return level;
+ }
+
+ public String getMessage() {
+ return "Invalid level for method " + method + " : " + level;
+ }
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/JavaLoggingMonitorFactory.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/JavaLoggingMonitorFactory.java
new file mode 100644
index 0000000000..daef77d4ae
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/JavaLoggingMonitorFactory.java
@@ -0,0 +1,186 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.monitor.impl;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.WeakHashMap;
+import java.util.ResourceBundle;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.LogRecord;
+
+import org.apache.tuscany.common.monitor.LogLevel;
+import org.apache.tuscany.common.monitor.MonitorFactory;
+
+/**
+ * A factory for monitors that forwards events to a {@link java.util.logging.Logger Java Logging (JSR47) Logger}.
+ *
+ * @version $Rev$ $Date$
+ * @see java.util.logging
+ */
+public class JavaLoggingMonitorFactory implements MonitorFactory {
+ private final String bundleName;
+ private final Level defaultLevel;
+ private final Map<String, Level> levels;
+
+ private final Map<Class<?>, WeakReference<?>> proxies = new WeakHashMap<Class<?>, WeakReference<?>>();
+
+ /**
+ * Construct a MonitorFactory that will monitor the specified methods at the specified levels
+ * and generate messages using java.util.logging.
+ * <p/>
+ * The supplied Properties can be used to specify custom log levels for specific monitor
+ * methods. The key should be the method name in form returned by
+ * <code>Class.getName() + '#' + Method.getName()</code> and the value the log level to use
+ * as defined by {@link java.util.logging.Level}.
+ *
+ * @param levels definition of custom levels for specific monitored methods
+ * @param defaultLevel the default log level to use
+ * @param bundleName the name of a resource bundle that will be passed to the logger
+ * @see java.util.logging.Logger
+ */
+ public JavaLoggingMonitorFactory(Properties levels, Level defaultLevel, String bundleName) {
+ this.defaultLevel = defaultLevel;
+ this.bundleName = bundleName;
+ this.levels = new HashMap<String, Level>(levels.size());
+ for (Map.Entry<Object, Object> entry : levels.entrySet()) {
+ String method = (String) entry.getKey();
+ String level = (String) entry.getValue();
+ try {
+ this.levels.put(method, Level.parse(level));
+ } catch (IllegalArgumentException e) {
+ throw new InvalidLevelException(method, level);
+ }
+ }
+ }
+
+ public synchronized <T> T getMonitor(Class<T> monitorInterface) {
+ T proxy = getCachedMonitor(monitorInterface);
+ if (proxy == null) {
+ proxy = createMonitor(monitorInterface, bundleName);
+ proxies.put(monitorInterface, new WeakReference<T>(proxy));
+ }
+ return proxy;
+ }
+
+ private <T>T getCachedMonitor(Class<T> monitorInterface) {
+ WeakReference<?> ref = proxies.get(monitorInterface);
+ return (ref != null) ? monitorInterface.cast(ref.get()) : null;
+ }
+
+ private <T>T createMonitor(Class<T> monitorInterface, String bundleName) {
+ String className = monitorInterface.getName();
+ Logger logger = Logger.getLogger(className);
+ Method[] methods = monitorInterface.getMethods();
+ Map<String, Level> levels = new HashMap<String, Level>(methods.length);
+ for (Method method : methods) {
+ String key = className + '#' + method.getName();
+ Level level = this.levels.get(key);
+
+ // if not specified the in config properties, look for an annotation on the method
+ if (level == null) {
+ LogLevel annotation = method.getAnnotation(LogLevel.class);
+ if (annotation != null && annotation.value() != null) {
+ try {
+ level = Level.parse(annotation.value());
+ } catch (IllegalArgumentException e) {
+ // bad value, just use the default
+ level = defaultLevel;
+ }
+ }
+ }
+ if (level == null) {
+ level = defaultLevel;
+ }
+ levels.put(method.getName(), level);
+ }
+
+ ResourceBundle bundle = locateBundle(monitorInterface, bundleName);
+
+ InvocationHandler handler = new LoggingHandler(logger, levels, bundle);
+ return monitorInterface.cast(Proxy.newProxyInstance(monitorInterface.getClassLoader(), new Class<?>[]{monitorInterface}, handler));
+ }
+
+ private static <T>ResourceBundle locateBundle(Class<T> monitorInterface, String bundleName) {
+ Locale locale = Locale.getDefault();
+ ClassLoader cl = monitorInterface.getClassLoader();
+ String packageName = monitorInterface.getPackage().getName();
+ while (true) {
+ try {
+ return ResourceBundle.getBundle(packageName + '.' + bundleName, locale, cl);
+ } catch (MissingResourceException e) {
+ }
+ int index = packageName.lastIndexOf('.');
+ if (index == -1) {
+ break;
+ }
+ packageName = packageName.substring(0, index);
+ }
+ try {
+ return ResourceBundle.getBundle(bundleName, locale, cl);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static final class LoggingHandler implements InvocationHandler {
+ private final Logger logger;
+ private final Map<String, Level> methodLevels;
+ private final ResourceBundle bundle;
+
+ public LoggingHandler(Logger logger, Map<String, Level> methodLevels, ResourceBundle bundle) {
+ this.logger = logger;
+ this.methodLevels = methodLevels;
+ this.bundle = bundle;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String sourceMethod = method.getName();
+ Level level = methodLevels.get(sourceMethod);
+ if (level != null && logger.isLoggable(level)) {
+ // construct the key for the resource bundle
+ String className = logger.getName();
+ String key = className + '#' + sourceMethod;
+
+ LogRecord logRecord = new LogRecord(level, key);
+ logRecord.setLoggerName(className);
+ logRecord.setSourceClassName(className);
+ logRecord.setSourceMethodName(sourceMethod);
+ logRecord.setParameters(args);
+ if (args != null) {
+ for (Object o : args) {
+ if (o instanceof Throwable) {
+ logRecord.setThrown((Throwable) o);
+ break;
+ }
+ }
+ }
+ logRecord.setResourceBundle(bundle);
+ logger.log(logRecord);
+ }
+ return null;
+ }
+ }
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/NullMonitorFactory.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/NullMonitorFactory.java
new file mode 100644
index 0000000000..827aeec84c
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/monitor/impl/NullMonitorFactory.java
@@ -0,0 +1,48 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.monitor.impl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import org.apache.tuscany.common.monitor.MonitorFactory;
+
+/**
+ * Implementation of a {@link MonitorFactory} that produces implementations that simply return.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NullMonitorFactory implements MonitorFactory {
+ public <T> T getMonitor(Class<T> monitorInterface) {
+ /*
+ * This uses a reflection proxy to implement the monitor interface which
+ * is a simple but perhaps not very performant solution. Performance
+ * might be improved by code generating an implementation with empty methods.
+ */
+ return monitorInterface.cast(Proxy.newProxyInstance(monitorInterface.getClassLoader(), new Class<?>[]{monitorInterface}, NULL_MONITOR));
+ }
+
+ /**
+ * Singleton wire hander that does nothing.
+ */
+ private static final InvocationHandler NULL_MONITOR = new InvocationHandler() {
+ public Object invoke(Object proxy, Method method, Object[] args) {
+ return null;
+ }
+ };
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/ResourceLoader.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/ResourceLoader.java
new file mode 100644
index 0000000000..897c5e06c0
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/ResourceLoader.java
@@ -0,0 +1,90 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.resource;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Interface which abstracts the implementation of something that is able to
+ * load resources (such as a ClassLoader). All Tuscany code should use this
+ * API rather than a ClassLoader directly in order to reduce the risk of
+ * memory leaks due to ClassLoader references.
+ *
+ * @version $Rev: 379878 $ $Date: 2006-02-22 12:45:50 -0800 (Wed, 22 Feb 2006) $
+ */
+public interface ResourceLoader {
+
+ /**
+ * Returns the parent resource loaders.
+ *
+ * @return resource loaders that are parents to this one
+ */
+ List<ResourceLoader> getParents();
+
+ /**
+ * Loads the class with the specified binary name.
+ *
+ * @param name the binary name of the class
+ * @return the resulting Class object
+ * @throws ClassNotFoundException if the class was not found
+ * @see ClassLoader#loadClass(String)
+ */
+ Class<?> loadClass(String name) throws ClassNotFoundException;
+
+ /**
+ * Converts an array of bytes into a Class.
+ *
+ * @param bytes the bytecode for the class; must match the class file format
+ * @return a Class defined from the supplied bytecode
+ */
+ Class<?> addClass(byte[] bytes);
+
+ /**
+ * Finds the first resource with the given name.
+ * <p/>
+ * Each parent is searched first (in the order returned by {@link #getParents()})
+ * and the first resource located is found. If no parent returns a resource then
+ * the first resource defined by this ResourceLoader is returned.
+ *
+ * @param name the resource name
+ * @return a {@link URL} that can be used to read the resource, or null if no resource could be found
+ */
+ URL getResource(String name);
+
+ /**
+ * Find resources with the given name that are available from this
+ * ResourceLoader or any of its parents.
+ *
+ * @param name the resource name
+ * @return an Iterator of {@link URL} objects for the resource
+ * @throws IOException if there was a problem locating the resources
+ */
+ Iterator<URL> getResources(String name) throws IOException;
+
+ //FIXME this is temporary to work around classloader problems with SDO when running in Tomcat
+
+ /**
+ * Returns the underlying classloader this loader is wrapping.
+ *
+ * @return the underlying classloader this loader is wrapping
+ */
+ ClassLoader getClassLoader();
+
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/GeneratedClassLoader.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/GeneratedClassLoader.java
new file mode 100644
index 0000000000..953908b9f2
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/GeneratedClassLoader.java
@@ -0,0 +1,45 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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 org.apache.tuscany.common.resource.impl;
+
+/**
+ * A class loader that allows new classes to be defined from an array of bytes.
+ *
+ * @version $Rev: 369102 $ $Date: 2006-01-14 13:48:56 -0800 (Sat, 14 Jan 2006) $
+ */
+@SuppressWarnings({"CustomClassloader"})
+class GeneratedClassLoader extends ClassLoader {
+
+ /**
+ * Constructs a new GeneratedClassLoader.
+ * @param classLoader the parent classloader
+ */
+ GeneratedClassLoader(ClassLoader classLoader) {
+ super(classLoader);
+ }
+
+ /**
+ * Converts an array of bytes into a Class.
+ *
+ * @param bytes the bytecode for the class; must match the class file format
+ * @return a Class defined from the supplied bytecode
+ */
+ Class<?> addClass(byte[] bytes) {
+ return defineClass(null, bytes, 0, bytes.length);
+ }
+
+}
diff --git a/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/ResourceLoaderImpl.java b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/ResourceLoaderImpl.java
new file mode 100644
index 0000000000..d306edf3b4
--- /dev/null
+++ b/sca-java-1.x/branches/java-post-M1/sca/common/src/main/java/org/apache/tuscany/common/resource/impl/ResourceLoaderImpl.java
@@ -0,0 +1,137 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed 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 org.apache.tuscany.common.resource.impl;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+
+/**
+ * Default implementation of the ResourceLoader interface
+ *
+ * @version $Rev: 369102 $ $Date: 2006-01-14 13:48:56 -0800 (Sat, 14 Jan 2006) $
+ */
+@SuppressWarnings({"ClassLoader2Instantiation"})
+public class ResourceLoaderImpl implements ResourceLoader {
+ private final WeakReference<ClassLoader> classLoaderReference;
+ private WeakReference<GeneratedClassLoader> generatedClassLoaderReference;
+ private final List<ResourceLoader> parents;
+
+ /**
+ * Constructs a new ResourceLoaderImpl to wrap a ClassLoader.
+ *
+ * @param classLoader the classloader to wrap
+ */
+ public ResourceLoaderImpl(ClassLoader classLoader) {
+ classLoaderReference = new WeakReference<ClassLoader>(classLoader);
+ generatedClassLoaderReference = new WeakReference<GeneratedClassLoader>(new GeneratedClassLoader(classLoader));
+ ClassLoader parentCL = classLoader.getParent();
+ if (null == parentCL) {
+ parents = Collections.emptyList();
+ } else {
+ parents = Collections.singletonList((ResourceLoader) new ResourceLoaderImpl(parentCL));
+ }
+ }
+
+
+ public ClassLoader getClassLoader() throws IllegalStateException {
+ ClassLoader cl = classLoaderReference.get();
+ if (cl == null) {
+ throw new IllegalStateException("Referenced ClassLoader has been garbage collected");
+ }
+ return cl;
+ }
+
+ public List<ResourceLoader> getParents() {
+ return parents;
+ }
+
+ public Class<?> loadClass(String name) throws ClassNotFoundException {
+ GeneratedClassLoader cl = generatedClassLoaderReference.get();
+ if (cl != null) {
+ return Class.forName(name, true, cl);
+ } else {
+ return Class.forName(name, true, getClassLoader());
+ }
+ }
+
+ public Class<?> addClass(byte[] bytes) {
+ GeneratedClassLoader cl = generatedClassLoaderReference.get();
+ if (cl == null) {
+ cl = new GeneratedClassLoader(getClassLoader());
+ generatedClassLoaderReference = new WeakReference<GeneratedClassLoader>(cl);
+ }
+ return cl.addClass(bytes);
+ }
+
+ public Iterator<URL> getResources(String name) throws IOException {
+ return new EnumerationIterator<URL>(getClassLoader().getResources(name));
+ }
+
+ public URL getResource(String name) {
+ return getClassLoader().getResource(name);
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof ResourceLoaderImpl)) {
+ return false;
+ }
+ final ResourceLoaderImpl other = (ResourceLoaderImpl) obj;
+ return getClassLoader() == other.getClassLoader();
+ }
+
+ public int hashCode() {
+ return getClassLoader().hashCode();
+ }
+
+ private static class EnumerationIterator<E> implements Iterator<E> {
+ private final Enumeration<E> e;
+
+ public EnumerationIterator(Enumeration<E> e) {
+ this.e = e;
+ }
+
+ public boolean hasNext() {
+ return e.hasMoreElements();
+ }
+
+ public E next() {
+ // the try/catch is needed here to get IDEA to shut up
+ // there should be no performance overhead here except when the Exception is thrown
+ // so I am going to leave it in - feel free to remove if there is any issue
+ try {
+ return e.nextElement();
+ } catch (NoSuchElementException e1) {
+ throw e1;
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}