You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2010/05/28 09:52:36 UTC
svn commit: r949127 [3/5] - in /camel/trunk: components/
components/camel-blueprint/
components/camel-blueprint/src/main/java/org/apache/camel/blueprint/
components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/
components/camel-blue...
Added: camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTracker.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTracker.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTracker.java (added)
+++ camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTracker.java Fri May 28 07:52:33 2010
@@ -0,0 +1,464 @@
+/**
+ * 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.
+ */
+
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ *
+ * 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.camel.core.osgi.tracker;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * The <code>BundleTracker</code> class simplifies tracking bundles much like
+ * the <code>ServiceTracker</code> simplifies tracking services.
+ * <p>
+ * A <code>BundleTracker</code> is constructed with state criteria and a
+ * <code>BundleTrackerCustomizer</code> object. A <code>BundleTracker</code> can
+ * use the <code>BundleTrackerCustomizer</code> to select which bundles are
+ * tracked and to create a customized object to be tracked with the bundle. The
+ * <code>BundleTracker</code> can then be opened to begin tracking all bundles
+ * whose state matches the specified state criteria.
+ * <p>
+ * The <code>getBundles</code> method can be called to get the
+ * <code>Bundle</code> objects of the bundles being tracked. The
+ * <code>getObject</code> method can be called to get the customized object for
+ * a tracked bundle.
+ * <p>
+ * The <code>BundleTracker</code> class is thread-safe. It does not call a
+ * <code>BundleTrackerCustomizer</code> while holding any locks.
+ * <code>BundleTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ *
+ * @ThreadSafe
+ * @version $Revision: 824648 $
+ * @since 1.4
+ */
+public class BundleTracker implements BundleTrackerCustomizer {
+ /* set this to true to compile in debug messages */
+ static final boolean DEBUG = false;
+
+ /**
+ * The Bundle Context used by this <code>BundleTracker</code>.
+ */
+ protected final BundleContext context;
+
+ /**
+ * State mask for bundles being tracked. This field contains the ORed values
+ * of the bundle states being tracked.
+ */
+ final int mask;
+
+ /**
+ * The <code>BundleTrackerCustomizer</code> object for this tracker.
+ */
+ final BundleTrackerCustomizer customizer;
+
+ /**
+ * Tracked bundles: <code>Bundle</code> object -> customized Object and
+ * <code>BundleListener</code> object
+ */
+ private volatile Tracked tracked;
+
+ /**
+ * Create a <code>BundleTracker</code> for bundles whose state is present in
+ * the specified state mask.
+ * <p>
+ * Bundles whose state is present on the specified state mask will be
+ * tracked by this <code>BundleTracker</code>.
+ *
+ * @param context The <code>BundleContext</code> against which the tracking
+ * is done.
+ * @param stateMask The bit mask of the <code>OR</code>ing of the bundle
+ * states to be tracked.
+ * @param customizer The customizer object to call when bundles are added,
+ * modified, or removed in this <code>BundleTracker</code>. If
+ * customizer is <code>null</code>, then this
+ * <code>BundleTracker</code> will be used as the
+ * <code>BundleTrackerCustomizer</code> and this
+ * <code>BundleTracker</code> will call the
+ * <code>BundleTrackerCustomizer</code> methods on itself.
+ * @see Bundle#getState()
+ */
+ public BundleTracker(BundleContext context, int stateMask, BundleTrackerCustomizer customizer) {
+ this.context = context;
+ this.mask = stateMask;
+ this.customizer = (customizer == null) ? this : customizer;
+ }
+
+ /**
+ * Accessor method for the current Tracked object. This method is only
+ * intended to be used by the unsynchronized methods which do not modify the
+ * tracked field.
+ *
+ * @return The current Tracked object.
+ */
+ private Tracked tracked() {
+ return tracked;
+ }
+
+
+ /**
+ * Open this <code>BundleTracker</code> and begin tracking bundles.
+ * <p>
+ * Bundle which match the state criteria specified when this
+ * <code>BundleTracker</code> was created are now tracked by this
+ * <code>BundleTracker</code>.
+ *
+ * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+ * with which this <code>BundleTracker</code> was created is no
+ * longer valid.
+ * @throws java.lang.SecurityException If the caller and this class do not
+ * have the appropriate
+ * <code>AdminPermission[context bundle,LISTENER]</code>, and
+ * the Java Runtime Environment supports permissions.
+ */
+ public void open() {
+ final Tracked t;
+ synchronized (this) {
+ if (tracked != null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("BundleTracker.open"); //$NON-NLS-1$
+ }
+ t = new Tracked();
+ synchronized (t) {
+ context.addBundleListener(t);
+ Bundle[] bundles = context.getBundles();
+ if (bundles != null) {
+ int length = bundles.length;
+ for (int i = 0; i < length; i++) {
+ int state = bundles[i].getState();
+ if ((state & mask) == 0) {
+ /* null out bundles whose states are not interesting */
+ bundles[i] = null;
+ }
+ }
+ /* set tracked with the initial bundles */
+ t.setInitial(bundles);
+ }
+ }
+ tracked = t;
+ }
+ /* Call tracked outside of synchronized region */
+ t.trackInitial(); /* process the initial references */
+ }
+
+ /**
+ * Close this <code>BundleTracker</code>.
+ * <p>
+ * This method should be called when this <code>BundleTracker</code> should
+ * end the tracking of bundles.
+ * <p>
+ * This implementation calls {@link #getBundles()} to get the list of
+ * tracked bundles to remove.
+ */
+ public void close() {
+ final Bundle[] bundles;
+ final Tracked outgoing;
+ synchronized (this) {
+ outgoing = tracked;
+ if (outgoing == null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("BundleTracker.close"); //$NON-NLS-1$
+ }
+ outgoing.close();
+ bundles = getBundles();
+ tracked = null;
+ try {
+ context.removeBundleListener(outgoing);
+ } catch (IllegalStateException e) {
+ /* In case the context was stopped. */
+ }
+ }
+ if (bundles != null) {
+ for (int i = 0; i < bundles.length; i++) {
+ outgoing.untrack(bundles[i], null);
+ }
+ }
+ }
+
+ /**
+ * Default implementation of the
+ * <code>BundleTrackerCustomizer.addingBundle</code> method.
+ * <p>
+ * This method is only called when this <code>BundleTracker</code> has been
+ * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+ * <p>
+ * This implementation simply returns the specified <code>Bundle</code>.
+ * <p>
+ * This method can be overridden in a subclass to customize the object to be
+ * tracked for the bundle being added.
+ *
+ * @param bundle The <code>Bundle</code> being added to this
+ * <code>BundleTracker</code> object.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event
+ * associated with the call to this method.
+ * @return The specified bundle.
+ * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
+ */
+ public Object addingBundle(Bundle bundle, BundleEvent event) {
+ return bundle;
+ }
+
+ /**
+ * Default implementation of the
+ * <code>BundleTrackerCustomizer.modifiedBundle</code> method.
+ * <p>
+ * This method is only called when this <code>BundleTracker</code> has been
+ * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+ * <p>
+ * This implementation does nothing.
+ *
+ * @param bundle The <code>Bundle</code> whose state has been modified.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event
+ * associated with the call to this method.
+ * @param object The customized object for the specified Bundle.
+ * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
+ */
+ public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+ /* do nothing */
+ }
+
+ /**
+ * Default implementation of the
+ * <code>BundleTrackerCustomizer.removedBundle</code> method.
+ * <p>
+ * This method is only called when this <code>BundleTracker</code> has been
+ * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+ * <p>
+ * This implementation does nothing.
+ *
+ * @param bundle The <code>Bundle</code> being removed.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event
+ * associated with the call to this method.
+ * @param object The customized object for the specified bundle.
+ * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
+ */
+ public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+ /* do nothing */
+ }
+
+ /**
+ * Return an array of <code>Bundle</code>s for all bundles being tracked by
+ * this <code>BundleTracker</code>.
+ *
+ * @return An array of <code>Bundle</code>s or <code>null</code> if no
+ * bundles are being tracked.
+ */
+ public Bundle[] getBundles() {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return null;
+ }
+ synchronized (t) {
+ int length = t.size();
+ if (length == 0) {
+ return null;
+ }
+ return (Bundle[])t.getTracked(new Bundle[length]);
+ }
+ }
+
+ /**
+ * Returns the customized object for the specified <code>Bundle</code> if
+ * the specified bundle is being tracked by this <code>BundleTracker</code>.
+ *
+ * @param bundle The <code>Bundle</code> being tracked.
+ * @return The customized object for the specified <code>Bundle</code> or
+ * <code>null</code> if the specified <code>Bundle</code> is not
+ * being tracked.
+ */
+ public Object getObject(Bundle bundle) {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return null;
+ }
+ synchronized (t) {
+ return t.getCustomizedObject(bundle);
+ }
+ }
+
+ /**
+ * Remove a bundle from this <code>BundleTracker</code>. The specified
+ * bundle will be removed from this <code>BundleTracker</code> . If the
+ * specified bundle was being tracked then the
+ * <code>BundleTrackerCustomizer.removedBundle</code> method will be called
+ * for that bundle.
+ *
+ * @param bundle The <code>Bundle</code> to be removed.
+ */
+ public void remove(Bundle bundle) {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return;
+ }
+ t.untrack(bundle, null);
+ }
+
+ /**
+ * Return the number of bundles being tracked by this
+ * <code>BundleTracker</code>.
+ *
+ * @return The number of bundles being tracked.
+ */
+ public int size() {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return 0;
+ }
+ synchronized (t) {
+ return t.size();
+ }
+ }
+
+ /**
+ * Returns the tracking count for this <code>BundleTracker</code>. The
+ * tracking count is initialized to 0 when this <code>BundleTracker</code>
+ * is opened. Every time a bundle is added, modified or removed from this
+ * <code>BundleTracker</code> the tracking count is incremented.
+ * <p>
+ * The tracking count can be used to determine if this
+ * <code>BundleTracker</code> has added, modified or removed a bundle by
+ * comparing a tracking count value previously collected with the current
+ * tracking count value. If the value has not changed, then no bundle has
+ * been added, modified or removed from this <code>BundleTracker</code>
+ * since the previous tracking count was collected.
+ *
+ * @return The tracking count for this <code>BundleTracker</code> or -1 if
+ * this <code>BundleTracker</code> is not open.
+ */
+ public int getTrackingCount() {
+ final Tracked t = tracked();
+ if (t == null) { /* if BundleTracker is not open */
+ return -1;
+ }
+ synchronized (t) {
+ return t.getTrackingCount();
+ }
+ }
+
+ /**
+ * Inner class which subclasses AbstractTracked. This class is the
+ * <code>SynchronousBundleListener</code> object for the tracker.
+ *
+ * @ThreadSafe
+ * @since 1.4
+ */
+ class Tracked extends AbstractTracked implements SynchronousBundleListener {
+ /**
+ * Tracked constructor.
+ */
+ Tracked() {
+ super();
+ }
+
+ /**
+ * <code>BundleListener</code> method for the <code>BundleTracker</code>
+ * class. This method must NOT be synchronized to avoid deadlock
+ * potential.
+ *
+ * @param event <code>BundleEvent</code> object from the framework.
+ */
+ public void bundleChanged(final BundleEvent event) {
+ /*
+ * Check if we had a delayed call (which could happen when we
+ * close).
+ */
+ if (closed) {
+ return;
+ }
+ final Bundle bundle = event.getBundle();
+ final int state = bundle.getState();
+ if (DEBUG) {
+ System.out.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if ((state & mask) != 0) {
+ track(bundle, event);
+ /*
+ * If the customizer throws an unchecked exception, it is safe
+ * to let it propagate
+ */
+ } else {
+ untrack(bundle, event);
+ /*
+ * If the customizer throws an unchecked exception, it is safe
+ * to let it propagate
+ */
+ }
+ }
+
+ /**
+ * Call the specific customizer adding method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Item to be tracked.
+ * @param related Action related object.
+ * @return Customized object for the tracked item or <code>null</code>
+ * if the item is not to be tracked.
+ */
+ Object customizerAdding(final Object item, final Object related) {
+ return customizer.addingBundle((Bundle)item, (BundleEvent)related);
+ }
+
+ /**
+ * Call the specific customizer modified method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ void customizerModified(final Object item, final Object related, final Object object) {
+ customizer.modifiedBundle((Bundle)item, (BundleEvent)related, object);
+ }
+
+ /**
+ * Call the specific customizer removed method. This method must not be
+ * called while synchronized on this object.
+ *
+ * @param item Tracked item.
+ * @param related Action related object.
+ * @param object Customized object for the tracked item.
+ */
+ void customizerRemoved(final Object item, final Object related, final Object object) {
+ customizer.removedBundle((Bundle)item, (BundleEvent)related, object);
+ }
+ }
+}
Added: camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTrackerCustomizer.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTrackerCustomizer.java (added)
+++ camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/tracker/BundleTrackerCustomizer.java Fri May 28 07:52:33 2010
@@ -0,0 +1,116 @@
+/**
+ * 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.
+ */
+
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). All Rights Reserved.
+ *
+ * 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.camel.core.osgi.tracker;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+
+/**
+ * The <code>BundleTrackerCustomizer</code> interface allows a
+ * <code>BundleTracker</code> to customize the <code>Bundle</code>s that are
+ * tracked. A <code>BundleTrackerCustomizer</code> is called when a bundle is
+ * being added to a <code>BundleTracker</code>. The
+ * <code>BundleTrackerCustomizer</code> can then return an object for the
+ * tracked bundle. A <code>BundleTrackerCustomizer</code> is also called when a
+ * tracked bundle is modified or has been removed from a
+ * <code>BundleTracker</code>.
+ *
+ * <p>
+ * The methods in this interface may be called as the result of a
+ * <code>BundleEvent</code> being received by a <code>BundleTracker</code>.
+ * Since <code>BundleEvent</code>s are received synchronously by the
+ * <code>BundleTracker</code>, it is highly recommended that implementations of
+ * these methods do not alter bundle states while being synchronized on any
+ * object.
+ *
+ * <p>
+ * The <code>BundleTracker</code> class is thread-safe. It does not call a
+ * <code>BundleTrackerCustomizer</code> while holding any locks.
+ * <code>BundleTrackerCustomizer</code> implementations must also be
+ * thread-safe.
+ *
+ * @ThreadSafe
+ * @version $Revision: 824648 $
+ * @since 1.4
+ */
+public interface BundleTrackerCustomizer {
+ /**
+ * A bundle is being added to the <code>BundleTracker</code>.
+ * <p>
+ * This method is called before a bundle which matched the search parameters
+ * of the <code>BundleTracker</code> is added to the
+ * <code>BundleTracker</code>. This method should return the object to be
+ * tracked for the specified <code>Bundle</code>. The returned object is
+ * stored in the <code>BundleTracker</code> and is available from the
+ * {@link BundleTracker#getObject(Bundle) getObject} method.
+ *
+ * @param bundle The <code>Bundle</code> being added to the
+ * <code>BundleTracker</code>.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event
+ * associated with the call to this method.
+ * @return The object to be tracked for the specified <code>Bundle</code>
+ * object or <code>null</code> if the specified <code>Bundle</code>
+ * object should not be tracked.
+ */
+ Object addingBundle(Bundle bundle, BundleEvent event);
+
+ /**
+ * A bundle tracked by the <code>BundleTracker</code> has been modified.
+ * <p>
+ * This method is called when a bundle being tracked by the
+ * <code>BundleTracker</code> has had its state modified.
+ *
+ * @param bundle The <code>Bundle</code> whose state has been modified.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event
+ * associated with the call to this method.
+ * @param object The tracked object for the specified bundle.
+ */
+ void modifiedBundle(Bundle bundle, BundleEvent event, Object object);
+
+ /**
+ * A bundle tracked by the <code>BundleTracker</code> has been removed.
+ * <p>
+ * This method is called after a bundle is no longer being tracked by the
+ * <code>BundleTracker</code>.
+ *
+ * @param bundle The <code>Bundle</code> that has been removed.
+ * @param event The bundle event which caused this customizer method to be
+ * called or <code>null</code> if there is no bundle event
+ * associated with the call to this method.
+ * @param object The tracked object for the specified bundle.
+ */
+ void removedBundle(Bundle bundle, BundleEvent event, Object object);
+}
Added: camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/utils/BundleDelegatingClassLoader.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/utils/BundleDelegatingClassLoader.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/utils/BundleDelegatingClassLoader.java (added)
+++ camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/utils/BundleDelegatingClassLoader.java Fri May 28 07:52:33 2010
@@ -0,0 +1,87 @@
+/*
+ * 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 org.apache.camel.core.osgi.utils;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A ClassLoader delegating to a given OSGi bundle.
+ *
+ * @version $Rev: 896324 $, $Date: 2010-01-06 07:05:04 +0100 (Wed, 06 Jan 2010) $
+ */
+public class BundleDelegatingClassLoader extends ClassLoader {
+
+ private final Bundle bundle;
+ private final ClassLoader classLoader;
+
+ public BundleDelegatingClassLoader(Bundle bundle) {
+ this(bundle, null);
+ }
+
+ public BundleDelegatingClassLoader(Bundle bundle, ClassLoader classLoader) {
+ this.bundle = bundle;
+ this.classLoader = classLoader;
+ }
+
+ protected Class findClass(String name) throws ClassNotFoundException {
+ return bundle.loadClass(name);
+ }
+
+ protected URL findResource(String name) {
+ URL resource = bundle.getResource(name);
+ if (classLoader != null && resource == null) {
+ resource = classLoader.getResource(name);
+ }
+ return resource;
+ }
+
+ protected Enumeration findResources(String name) throws IOException {
+ return bundle.getResources(name);
+ }
+
+ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ Class clazz;
+ try {
+ clazz = findClass(name);
+ }
+ catch (ClassNotFoundException cnfe) {
+ if (classLoader != null) {
+ try {
+ clazz = classLoader.loadClass(name);
+ } catch (ClassNotFoundException e) {
+ throw new ClassNotFoundException(name + " from bundle " + bundle.getBundleId() + " (" + bundle.getSymbolicName() + ")", cnfe);
+ }
+ } else {
+ throw new ClassNotFoundException(name + " from bundle " + bundle.getBundleId() + " (" + bundle.getSymbolicName() + ")", cnfe);
+ }
+ }
+ if (resolve) {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+
+ public Bundle getBundle() {
+ return bundle;
+ }
+}
Added: camel/trunk/components/camel-core-xml/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/pom.xml?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-xml/pom.xml (added)
+++ camel/trunk/components/camel-core-xml/pom.xml Fri May 28 07:52:33 2010
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-parent</artifactId>
+ <version>2.4-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-core-xml</artifactId>
+ <name>Camel :: Core XML</name>
+ <description>Camel Core XML support</description>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <childDelegation>false</childDelegation>
+ <useFile>true</useFile>
+ <forkMode>pertest</forkMode>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
+ <excludes>
+ <!-- TODO FIXME ASAP -->
+ <exclude>**/XXXTest.*</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelConsumerTemplateFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelConsumerTemplateFactoryBean.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelConsumerTemplateFactoryBean.java (added)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelConsumerTemplateFactoryBean.java Fri May 28 07:52:33 2010
@@ -0,0 +1,112 @@
+/**
+ * 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 org.apache.camel.core.xml;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.ConsumerTemplate;
+import org.apache.camel.impl.DefaultConsumerTemplate;
+import org.apache.camel.model.IdentifiedType;
+import org.apache.camel.util.ServiceHelper;
+
+/**
+ * A factory for creating a new {@link org.apache.camel.ConsumerTemplate}
+ * instance with a minimum of XML
+ *
+ * @version $Revision: 934375 $
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class AbstractCamelConsumerTemplateFactoryBean extends IdentifiedType implements CamelContextAware {
+ @XmlTransient
+ private ConsumerTemplate template;
+ @XmlAttribute
+ private String camelContextId;
+ @XmlTransient
+ private CamelContext camelContext;
+ @XmlAttribute
+ private Integer maximumCacheSize;
+
+ public void afterPropertiesSet() throws Exception {
+ if (camelContext == null && camelContextId != null) {
+ camelContext = getCamelContextWithId(camelContextId);
+ }
+ if (camelContext == null) {
+ throw new IllegalArgumentException("A CamelContext or a CamelContextId must be injected!");
+ }
+ }
+
+ protected abstract CamelContext getCamelContextWithId(String camelContextId);
+
+ public Object getObject() throws Exception {
+ template = new DefaultConsumerTemplate(camelContext);
+
+ // set custom cache size if provided
+ if (maximumCacheSize != null) {
+ template.setMaximumCacheSize(maximumCacheSize);
+ }
+
+ // must start it so its ready to use
+ ServiceHelper.startService(template);
+ return template;
+ }
+
+ public Class getObjectType() {
+ return DefaultConsumerTemplate.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void destroy() throws Exception {
+ ServiceHelper.stopService(template);
+ }
+
+ // Properties
+ // -------------------------------------------------------------------------
+
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ public String getCamelContextId() {
+ return camelContextId;
+ }
+
+ public void setCamelContextId(String camelContextId) {
+ this.camelContextId = camelContextId;
+ }
+
+ public Integer getMaximumCacheSize() {
+ return maximumCacheSize;
+ }
+
+ public void setMaximumCacheSize(Integer maximumCacheSize) {
+ this.maximumCacheSize = maximumCacheSize;
+ }
+}
\ No newline at end of file
Added: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java (added)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java Fri May 28 07:52:33 2010
@@ -0,0 +1,879 @@
+/**
+ * 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 org.apache.camel.core.xml;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelException;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.ShutdownRoute;
+import org.apache.camel.ShutdownRunningTask;
+import org.apache.camel.builder.ErrorHandlerBuilderRef;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.properties.PropertiesComponent;
+import org.apache.camel.component.properties.PropertiesResolver;
+import org.apache.camel.management.DefaultManagementAgent;
+import org.apache.camel.management.DefaultManagementLifecycleStrategy;
+import org.apache.camel.management.DefaultManagementStrategy;
+import org.apache.camel.management.ManagedManagementStrategy;
+import org.apache.camel.model.*;
+import org.apache.camel.model.config.PropertiesDefinition;
+import org.apache.camel.model.dataformat.DataFormatsDefinition;
+import org.apache.camel.processor.interceptor.Delayer;
+import org.apache.camel.processor.interceptor.HandleFault;
+import org.apache.camel.processor.interceptor.TraceFormatter;
+import org.apache.camel.processor.interceptor.Tracer;
+import org.apache.camel.spi.*;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.EndpointHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.core.xml.scan.PatternBasedPackageScanFilter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A factory to create and initialize a
+ * {@link CamelContext} and install routes either explicitly configured
+ * or found by searching the classpath for Java classes which extend
+ * {@link org.apache.camel.builder.RouteBuilder}.
+ *
+ * @version $Revision: 938746 $
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class AbstractCamelContextFactoryBean<T extends CamelContext> extends IdentifiedType implements RouteContainer {
+
+ private static final Log LOG = LogFactory.getLog(AbstractCamelContextFactoryBean.class);
+
+// @XmlAttribute(name = "depends-on", required = false)
+// private String dependsOn;
+// @XmlAttribute(required = false)
+// private String trace;
+// @XmlAttribute(required = false)
+// private String streamCache = "false";
+// @XmlAttribute(required = false)
+// private String delayer;
+// @XmlAttribute(required = false)
+// private String handleFault;
+// @XmlAttribute(required = false)
+// private String errorHandlerRef;
+// @XmlAttribute(required = false)
+// private String autoStartup = "true";
+// @XmlAttribute(required = false)
+// private ShutdownRoute shutdownRoute;
+// @XmlAttribute(required = false)
+// private ShutdownRunningTask shutdownRunningTask;
+// @XmlElement(name = "properties", required = false)
+// private PropertiesDefinition properties;
+// @XmlElement(name = "propertyPlaceholder", type = CamelPropertyPlaceholderDefinition.class, required = false)
+// private CamelPropertyPlaceholderDefinition camelPropertyPlaceholder;
+// @XmlElement(name = "package", required = false)
+// private String[] packages = {};
+// @XmlElement(name = "packageScan", type = PackageScanDefinition.class, required = false)
+// private PackageScanDefinition packageScan;
+// @XmlElement(name = "jmxAgent", type = CamelJMXAgentDefinition.class, required = false)
+// private CamelJMXAgentDefinition camelJMXAgent;
+//// @XmlElements({
+//// @XmlElement(name = "beanPostProcessor", type = CamelBeanPostProcessor.class, required = false),
+//// @XmlElement(name = "template", type = CamelProducerTemplateFactoryBean.class, required = false),
+//// @XmlElement(name = "consumerTemplate", type = CamelConsumerTemplateFactoryBean.class, required = false),
+//// @XmlElement(name = "proxy", type = CamelProxyFactoryDefinition.class, required = false),
+//// @XmlElement(name = "export", type = CamelServiceExporterDefinition.class, required = false),
+//// @XmlElement(name = "errorHandler", type = ErrorHandlerDefinition.class, required = false)})
+//// private List beans;
+// @XmlElement(name = "routeBuilder", required = false)
+// private List<RouteBuilderDefinition> builderRefs = new ArrayList<RouteBuilderDefinition>();
+// @XmlElement(name = "routeContextRef", required = false)
+// private List<RouteContextRefDefinition> routeRefs = new ArrayList<RouteContextRefDefinition>();
+// @XmlElement(name = "threadPoolProfile", required = false)
+// private List<ThreadPoolProfileDefinition> threadPoolProfiles;
+//// @XmlElement(name = "threadPool", required = false)
+//// private List<AbstractCamelThreadPoolFactoryBean> threadPools;
+//// @XmlElement(name = "endpoint", required = false)
+//// private List<AbstractCamelEndpointFactoryBean> endpoints;
+// @XmlElement(name = "dataFormats", required = false)
+// private DataFormatsDefinition dataFormats;
+// @XmlElement(name = "onException", required = false)
+// private List<OnExceptionDefinition> onExceptions = new ArrayList<OnExceptionDefinition>();
+// @XmlElement(name = "onCompletion", required = false)
+// private List<OnCompletionDefinition> onCompletions = new ArrayList<OnCompletionDefinition>();
+// @XmlElement(name = "intercept", required = false)
+// private List<InterceptDefinition> intercepts = new ArrayList<InterceptDefinition>();
+// @XmlElement(name = "interceptFrom", required = false)
+// private List<InterceptFromDefinition> interceptFroms = new ArrayList<InterceptFromDefinition>();
+// @XmlElement(name = "interceptSendToEndpoint", required = false)
+// private List<InterceptSendToEndpointDefinition> interceptSendToEndpoints = new ArrayList<InterceptSendToEndpointDefinition>();
+// @XmlElement(name = "route", required = false)
+// private List<RouteDefinition> routes = new ArrayList<RouteDefinition>();
+// @XmlTransient
+// private T context;
+ @XmlTransient
+ private List<RoutesBuilder> builders = new ArrayList<RoutesBuilder>();
+ @XmlTransient
+ private ClassLoader contextClassLoaderOnStart;
+
+ public AbstractCamelContextFactoryBean() {
+ // Lets keep track of the class loader for when we actually do start things up
+ contextClassLoaderOnStart = Thread.currentThread().getContextClassLoader();
+ }
+
+ public Object getObject() throws Exception {
+ return getContext();
+ }
+
+ public Class getObjectType() {
+ return CamelContext.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public ClassLoader getContextClassLoaderOnStart() {
+ return contextClassLoaderOnStart;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (ObjectHelper.isEmpty(getId())) {
+ throw new IllegalArgumentException("Id must be set");
+ }
+
+ if (getProperties() != null) {
+ getContext().setProperties(getProperties().asMap());
+ }
+
+ // set the resolvers first
+ PackageScanClassResolver packageResolver = getBeanForType(PackageScanClassResolver.class);
+ if (packageResolver != null) {
+ LOG.info("Using custom PackageScanClassResolver: " + packageResolver);
+ getContext().setPackageScanClassResolver(packageResolver);
+ }
+ ClassResolver classResolver = getBeanForType(ClassResolver.class);
+ if (classResolver != null) {
+ LOG.info("Using custom ClassResolver: " + classResolver);
+ getContext().setClassResolver(classResolver);
+ }
+ FactoryFinderResolver factoryFinderResolver = getBeanForType(FactoryFinderResolver.class);
+ if (factoryFinderResolver != null) {
+ LOG.info("Using custom FactoryFinderResolver: " + factoryFinderResolver);
+ getContext().setFactoryFinderResolver(factoryFinderResolver);
+ }
+ ExecutorServiceStrategy executorServiceStrategy = getBeanForType(ExecutorServiceStrategy.class);
+ if (executorServiceStrategy != null) {
+ LOG.info("Using custom ExecutorServiceStrategy: " + executorServiceStrategy);
+ getContext().setExecutorServiceStrategy(executorServiceStrategy);
+ }
+
+ // set the custom registry if defined
+ initCustomRegistry(getContext());
+
+ // setup property placeholder so we got it as early as possible
+ initPropertyPlaceholder();
+
+ // setup JMX agent at first
+ initJMXAgent();
+
+ Tracer tracer = getBeanForType(Tracer.class);
+ if (tracer != null) {
+ // use formatter if there is a TraceFormatter bean defined
+ TraceFormatter formatter = getBeanForType(TraceFormatter.class);
+ if (formatter != null) {
+ tracer.setFormatter(formatter);
+ }
+ LOG.info("Using custom Tracer: " + tracer);
+ getContext().addInterceptStrategy(tracer);
+ }
+
+ HandleFault handleFault = getBeanForType(HandleFault.class);
+ if (handleFault != null) {
+ LOG.info("Using custom HandleFault: " + handleFault);
+ getContext().addInterceptStrategy(handleFault);
+ }
+
+ Delayer delayer = getBeanForType(Delayer.class);
+ if (delayer != null) {
+ LOG.info("Using custom Delayer: " + delayer);
+ getContext().addInterceptStrategy(delayer);
+ }
+
+ InflightRepository inflightRepository = getBeanForType(InflightRepository.class);
+ if (delayer != null) {
+ LOG.info("Using custom InflightRepository: " + inflightRepository);
+ getContext().setInflightRepository(inflightRepository);
+ }
+
+ ManagementStrategy managementStrategy = getBeanForType(ManagementStrategy.class);
+ if (managementStrategy != null) {
+ LOG.info("Using custom ManagementStrategy: " + managementStrategy);
+ getContext().setManagementStrategy(managementStrategy);
+ }
+
+ EventFactory eventFactory = getBeanForType(EventFactory.class);
+ if (eventFactory != null) {
+ LOG.info("Using custom EventFactory: " + eventFactory);
+ getContext().getManagementStrategy().setEventFactory(eventFactory);
+ }
+
+ // set the event notifier strategies if defined
+ Map<String, EventNotifier> eventNotifiers = getContext().getRegistry().lookupByType(EventNotifier.class);
+ if (eventNotifiers != null && !eventNotifiers.isEmpty()) {
+ for (String id : eventNotifiers.keySet()) {
+ EventNotifier notifier = eventNotifiers.get(id);
+ // do not add if already added, for instance a tracer that is also an InterceptStrategy class
+ if (!getContext().getManagementStrategy().getEventNotifiers().contains(notifier)) {
+ LOG.info("Using custom EventNotifier with id: " + id + " and implementation: " + notifier);
+ getContext().getManagementStrategy().addEventNotifier(notifier);
+ }
+ }
+ }
+
+ ShutdownStrategy shutdownStrategy = getBeanForType(ShutdownStrategy.class);
+ if (shutdownStrategy != null) {
+ LOG.info("Using custom ShutdownStrategy: " + shutdownStrategy);
+ getContext().setShutdownStrategy(shutdownStrategy);
+ }
+
+ // add global interceptors
+ Map<String, InterceptStrategy> interceptStrategies = getContext().getRegistry().lookupByType(InterceptStrategy.class);
+ if (interceptStrategies != null && !interceptStrategies.isEmpty()) {
+ for (String id : interceptStrategies.keySet()) {
+ InterceptStrategy strategy = interceptStrategies.get(id);
+ // do not add if already added, for instance a tracer that is also an InterceptStrategy class
+ if (!getContext().getInterceptStrategies().contains(strategy)) {
+ LOG.info("Using custom InterceptStrategy with id: " + id + " and implementation: " + strategy);
+ getContext().addInterceptStrategy(strategy);
+ }
+ }
+ }
+
+ // set the lifecycle strategy if defined
+ Map<String, LifecycleStrategy> lifecycleStrategies = getContext().getRegistry().lookupByType(LifecycleStrategy.class);
+ if (lifecycleStrategies != null && !lifecycleStrategies.isEmpty()) {
+ for (String id : lifecycleStrategies.keySet()) {
+ LifecycleStrategy strategy = lifecycleStrategies.get(id);
+ // do not add if already added, for instance a tracer that is also an InterceptStrategy class
+ if (!getContext().getLifecycleStrategies().contains(strategy)) {
+ LOG.info("Using custom LifecycleStrategy with id: " + id + " and implementation: " + strategy);
+ getContext().addLifecycleStrategy(strategy);
+ }
+ }
+ }
+
+ // set the default thread pool profile if defined
+ initThreadPoolProfiles(getContext());
+
+ // Set the application context and camelContext for the beanPostProcessor
+ initBeanPostProcessor(getContext());
+
+ initCamelContext(getContext());
+
+ // must init route refs before we prepare the routes below
+ initRouteRefs();
+
+ // do special preparation for some concepts such as interceptors and policies
+ // this is needed as JAXB does not build exactly the same model definition as Spring DSL would do
+ // using route builders. So we have here a little custom code to fix the JAXB gaps
+ for (RouteDefinition route : getRoutes()) {
+
+ // abstracts is the cross cutting concerns
+ List<ProcessorDefinition> abstracts = new ArrayList<ProcessorDefinition>();
+
+ // upper is the cross cutting concerns such as interceptors, error handlers etc
+ List<ProcessorDefinition> upper = new ArrayList<ProcessorDefinition>();
+
+ // lower is the regular route
+ List<ProcessorDefinition> lower = new ArrayList<ProcessorDefinition>();
+
+ prepareRouteForInit(route, abstracts, lower);
+
+ // toAsync should fix up itself at first
+ initToAsync(lower);
+
+ // interceptors should be first for the cross cutting concerns
+ initInterceptors(route, upper);
+ // then on completion
+ initOnCompletions(abstracts, upper);
+ // then transactions
+ initTransacted(abstracts, lower);
+ // then on exception
+ initOnExceptions(abstracts, upper);
+
+ // rebuild route as upper + lower
+ route.clearOutput();
+ route.getOutputs().addAll(upper);
+ route.getOutputs().addAll(lower);
+
+ // configure parents
+ initParent(route);
+ }
+
+ if (getDataFormats() != null) {
+ getContext().setDataFormats(getDataFormats().asMap());
+ }
+
+ // lets force any lazy creation
+ getContext().addRouteDefinitions(getRoutes());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found JAXB created routes: " + getRoutes());
+ }
+ findRouteBuilders();
+ installRoutes();
+ }
+
+ protected abstract void initCustomRegistry(T context);
+
+ private void prepareRouteForInit(RouteDefinition route, List<ProcessorDefinition> abstracts,
+ List<ProcessorDefinition> lower) {
+ // filter the route into abstracts and lower
+ for (ProcessorDefinition output : route.getOutputs()) {
+ if (output.isAbstract()) {
+ abstracts.add(output);
+ } else {
+ lower.add(output);
+ }
+ }
+ }
+
+ private void initParent(RouteDefinition route) {
+ for (ProcessorDefinition output : route.getOutputs()) {
+ output.setParent(route);
+ if (output.getOutputs() != null) {
+ // recursive the outputs
+ initParent(output);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void initParent(ProcessorDefinition parent) {
+ List<ProcessorDefinition> children = parent.getOutputs();
+ for (ProcessorDefinition child : children) {
+ child.setParent(parent);
+ if (child.getOutputs() != null) {
+ // recursive the children
+ initParent(child);
+ }
+ }
+ }
+
+ private void initToAsync(List<ProcessorDefinition> lower) {
+ List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>();
+ ToDefinition toAsync = null;
+
+ for (ProcessorDefinition output : lower) {
+ if (toAsync != null) {
+ // add this output on toAsync
+ toAsync.getOutputs().add(output);
+ } else {
+ // regular outputs
+ outputs.add(output);
+ }
+
+ if (output instanceof ToDefinition) {
+ ToDefinition to = (ToDefinition) output;
+ if (to.isAsync() != null && to.isAsync()) {
+ // new current to async
+ toAsync = to;
+ }
+ }
+ }
+
+ // rebuild outputs
+ lower.clear();
+ lower.addAll(outputs);
+ }
+
+ private void initOnExceptions(List<ProcessorDefinition> abstracts, List<ProcessorDefinition> upper) {
+ // add global on exceptions if any
+ List<OnExceptionDefinition> onExceptions = getOnExceptions();
+ if (onExceptions != null && !onExceptions.isEmpty()) {
+ abstracts.addAll(onExceptions);
+ }
+
+ // now add onExceptions to the route
+ for (ProcessorDefinition output : abstracts) {
+ if (output instanceof OnExceptionDefinition) {
+ // on exceptions must be added at top, so the route flow is correct as
+ // on exceptions should be the first outputs
+ upper.add(0, output);
+ }
+ }
+ }
+
+ private void initInterceptors(RouteDefinition route, List<ProcessorDefinition> upper) {
+ // configure intercept
+ for (InterceptDefinition intercept : getIntercepts()) {
+ intercept.afterPropertiesSet();
+ // add as first output so intercept is handled before the actual route and that gives
+ // us the needed head start to init and be able to intercept all the remaining processing steps
+ upper.add(0, intercept);
+ }
+
+ // configure intercept from
+ for (InterceptFromDefinition intercept : getInterceptFroms()) {
+
+ // should we only apply interceptor for a given endpoint uri
+ boolean match = true;
+ if (intercept.getUri() != null) {
+ match = false;
+ for (FromDefinition input : route.getInputs()) {
+ if (EndpointHelper.matchEndpoint(input.getUri(), intercept.getUri())) {
+ match = true;
+ break;
+ }
+ }
+ }
+
+ if (match) {
+ intercept.afterPropertiesSet();
+ // add as first output so intercept is handled before the actual route and that gives
+ // us the needed head start to init and be able to intercept all the remaining processing steps
+ upper.add(0, intercept);
+ }
+ }
+
+ // configure intercept send to endpoint
+ for (InterceptSendToEndpointDefinition intercept : getInterceptSendToEndpoints()) {
+ intercept.afterPropertiesSet();
+ // add as first output so intercept is handled before the actual route and that gives
+ // us the needed head start to init and be able to intercept all the remaining processing steps
+ upper.add(0, intercept);
+ }
+ }
+
+ private void initOnCompletions(List<ProcessorDefinition> abstracts, List<ProcessorDefinition> upper) {
+ List<OnCompletionDefinition> completions = new ArrayList<OnCompletionDefinition>();
+
+ // find the route scoped onCompletions
+ for (ProcessorDefinition out : abstracts) {
+ if (out instanceof OnCompletionDefinition) {
+ completions.add((OnCompletionDefinition) out);
+ }
+ }
+
+ // only add global onCompletion if there are no route already
+ if (completions.isEmpty()) {
+ completions = getOnCompletions();
+ }
+
+ // are there any completions to init at all?
+ if (completions.isEmpty()) {
+ return;
+ }
+
+ upper.addAll(completions);
+ }
+
+ private void initTransacted(List<ProcessorDefinition> abstracts, List<ProcessorDefinition> lower) {
+ TransactedDefinition transacted = null;
+
+ // add to correct type
+ for (ProcessorDefinition type : abstracts) {
+ if (type instanceof TransactedDefinition) {
+ if (transacted == null) {
+ transacted = (TransactedDefinition) type;
+ } else {
+ throw new IllegalArgumentException("The route can only have one transacted defined");
+ }
+ }
+ }
+
+ if (transacted != null) {
+ // the outputs should be moved to the transacted policy
+ transacted.getOutputs().addAll(lower);
+ // and add it as the single output
+ lower.clear();
+ lower.add(transacted);
+ }
+ }
+
+ private void initJMXAgent() throws Exception {
+ CamelJMXAgentDefinition camelJMXAgent = getCamelJMXAgent();
+ if (camelJMXAgent != null && camelJMXAgent.isAgentDisabled()) {
+ LOG.info("JMXAgent disabled");
+ // clear the existing lifecycle strategies define by the DefaultCamelContext constructor
+ getContext().getLifecycleStrategies().clear();
+ // no need to add a lifecycle strategy as we do not need one as JMX is disabled
+ getContext().setManagementStrategy(new DefaultManagementStrategy());
+ } else if (camelJMXAgent != null) {
+ LOG.info("JMXAgent enabled: " + camelJMXAgent);
+ DefaultManagementAgent agent = new DefaultManagementAgent(getContext());
+ agent.setConnectorPort(parseInteger(camelJMXAgent.getConnectorPort()));
+ agent.setCreateConnector(parseBoolean(camelJMXAgent.getCreateConnector()));
+ agent.setMBeanObjectDomainName(parseText(camelJMXAgent.getMbeanObjectDomainName()));
+ agent.setMBeanServerDefaultDomain(parseText(camelJMXAgent.getMbeanServerDefaultDomain()));
+ agent.setRegistryPort(parseInteger(camelJMXAgent.getRegistryPort()));
+ agent.setServiceUrlPath(parseText(camelJMXAgent.getServiceUrlPath()));
+ agent.setUsePlatformMBeanServer(parseBoolean(camelJMXAgent.getUsePlatformMBeanServer()));
+ agent.setOnlyRegisterProcessorWithCustomId(parseBoolean(camelJMXAgent.getOnlyRegisterProcessorWithCustomId()));
+
+ ManagementStrategy managementStrategy = new ManagedManagementStrategy(agent);
+ getContext().setManagementStrategy(managementStrategy);
+
+ // clear the existing lifecycle strategies define by the DefaultCamelContext constructor
+ getContext().getLifecycleStrategies().clear();
+ getContext().addLifecycleStrategy(new DefaultManagementLifecycleStrategy(getContext()));
+ // set additional configuration from camelJMXAgent
+ boolean onlyId = agent.getOnlyRegisterProcessorWithCustomId() != null && agent.getOnlyRegisterProcessorWithCustomId();
+ getContext().getManagementStrategy().onlyManageProcessorWithCustomId(onlyId);
+ getContext().getManagementStrategy().setStatisticsLevel(camelJMXAgent.getStatisticsLevel());
+ }
+ }
+
+ private void initPropertyPlaceholder() throws Exception {
+ if (getCamelPropertyPlaceholder() != null) {
+ CamelPropertyPlaceholderDefinition def = getCamelPropertyPlaceholder();
+
+ PropertiesComponent pc = new PropertiesComponent();
+ pc.setLocation(def.getLocation());
+
+ // if using a custom resolver
+ if (ObjectHelper.isNotEmpty(def.getPropertiesResolverRef())) {
+ PropertiesResolver resolver = CamelContextHelper.mandatoryLookup(getContext(), def.getPropertiesResolverRef(),
+ PropertiesResolver.class);
+ pc.setPropertiesResolver(resolver);
+ }
+
+ // register the properties component
+ getContext().addComponent("properties", pc);
+ }
+ }
+
+ private void initRouteRefs() throws Exception {
+ // add route refs to existing routes
+ if (getRouteRefs() != null) {
+ for (RouteContextRefDefinition ref : getRouteRefs()) {
+ List<RouteDefinition> defs = ref.lookupRoutes(getContext());
+ for (RouteDefinition def : defs) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding route from " + ref + " -> " + def);
+ }
+ // add in top as they are most likely to be common/shared
+ // which you may want to start first
+ getRoutes().add(0, def);
+ }
+ }
+ }
+ }
+
+ protected abstract <S> S getBeanForType(Class<S> clazz);
+
+ public void destroy() throws Exception {
+ getContext().stop();
+ }
+
+ private String parseText(String text) throws Exception {
+ // ensure we support property placeholders
+ return getContext().resolvePropertyPlaceholders(text);
+ }
+
+ private Integer parseInteger(String text) throws Exception {
+ // ensure we support property placeholders
+ String s = getContext().resolvePropertyPlaceholders(text);
+ if (s != null) {
+ try {
+ return new Integer(s);
+ } catch (NumberFormatException e) {
+ if (s.equals(text)) {
+ throw new IllegalArgumentException("Error parsing [" + s + "] as an Integer.", e);
+ } else {
+ throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as an Integer.", e);
+ }
+ }
+ }
+ return null;
+ }
+
+ private Long parseLong(String text) throws Exception {
+ // ensure we support property placeholders
+ String s = getContext().resolvePropertyPlaceholders(text);
+ if (s != null) {
+ try {
+ return new Long(s);
+ } catch (NumberFormatException e) {
+ if (s.equals(text)) {
+ throw new IllegalArgumentException("Error parsing [" + s + "] as a Long.", e);
+ } else {
+ throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as a Long.", e);
+ }
+ }
+ }
+ return null;
+ }
+
+ private Boolean parseBoolean(String text) throws Exception {
+ // ensure we support property placeholders
+ String s = getContext().resolvePropertyPlaceholders(text);
+ if (s != null) {
+ s = s.trim().toLowerCase();
+ if (s.equals("true") || s.equals("false")) {
+ return new Boolean(s);
+ } else {
+ if (s.equals(text)) {
+ throw new IllegalArgumentException("Error parsing [" + s + "] as a Boolean.");
+ } else {
+ throw new IllegalArgumentException("Error parsing [" + s + "] from property " + text + " as a Boolean.");
+ }
+ }
+ }
+ return null;
+ }
+
+ // Properties
+ // -------------------------------------------------------------------------
+ public T getContext() {
+ return getContext(true);
+ }
+
+ public abstract T getContext(boolean create);
+
+ public abstract List<RouteDefinition> getRoutes();
+
+ public abstract List<InterceptDefinition> getIntercepts();
+
+ public abstract List<InterceptFromDefinition> getInterceptFroms();
+
+ public abstract List<InterceptSendToEndpointDefinition> getInterceptSendToEndpoints();
+
+ public abstract PropertiesDefinition getProperties();
+
+ public abstract String[] getPackages();
+
+ public abstract PackageScanDefinition getPackageScan();
+
+ public abstract void setPackageScan(PackageScanDefinition packageScan);
+
+ public abstract CamelPropertyPlaceholderDefinition getCamelPropertyPlaceholder();
+
+ public abstract String getTrace();
+
+ public abstract String getStreamCache();
+
+ public abstract String getDelayer();
+
+ public abstract String getHandleFault();
+
+ public abstract String getAutoStartup();
+
+ public abstract CamelJMXAgentDefinition getCamelJMXAgent();
+
+ public abstract List<RouteBuilderDefinition> getBuilderRefs();
+
+ public abstract List<RouteContextRefDefinition> getRouteRefs();
+
+ public abstract String getErrorHandlerRef();
+
+ public abstract DataFormatsDefinition getDataFormats();
+
+ public abstract List<OnExceptionDefinition> getOnExceptions();
+
+ public abstract List<OnCompletionDefinition> getOnCompletions();
+
+ public abstract ShutdownRoute getShutdownRoute();
+
+ public abstract ShutdownRunningTask getShutdownRunningTask();
+
+ public abstract List<ThreadPoolProfileDefinition> getThreadPoolProfiles();
+
+ public abstract String getDependsOn();
+
+ // Implementation methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * Initializes the context
+ *
+ * @param ctx the context
+ * @throws Exception is thrown if error occurred
+ */
+ protected void initCamelContext(T ctx) throws Exception {
+ if (getStreamCache() != null) {
+ ctx.setStreamCaching(parseBoolean(getStreamCache()));
+ }
+ if (getTrace() != null) {
+ ctx.setTracing(parseBoolean(getTrace()));
+ }
+ if (getDelayer() != null) {
+ ctx.setDelayer(parseLong(getDelayer()));
+ }
+ if (getHandleFault() != null) {
+ ctx.setHandleFault(parseBoolean(getHandleFault()));
+ }
+ if (getErrorHandlerRef() != null) {
+ ctx.setErrorHandlerBuilder(new ErrorHandlerBuilderRef(getErrorHandlerRef()));
+ }
+ if (getAutoStartup() != null) {
+ ctx.setAutoStartup(parseBoolean(getAutoStartup()));
+ }
+ if (getShutdownRoute() != null) {
+ ctx.setShutdownRoute(getShutdownRoute());
+ }
+ if (getShutdownRunningTask() != null) {
+ ctx.setShutdownRunningTask(getShutdownRunningTask());
+ }
+ }
+
+ private void initThreadPoolProfiles(T context) {
+ Set<String> defaultIds = new HashSet<String>();
+
+ // lookup and use custom profiles from the registry
+ Map<String, ThreadPoolProfile> profiles = context.getRegistry().lookupByType(ThreadPoolProfile.class);
+ if (profiles != null && !profiles.isEmpty()) {
+ for (String id : profiles.keySet()) {
+ ThreadPoolProfile profile = profiles.get(id);
+ // do not add if already added, for instance a tracer that is also an InterceptStrategy class
+ if (profile.isDefaultProfile()) {
+ LOG.info("Using custom default ThreadPoolProfile with id: " + id + " and implementation: " + profile);
+ context.getExecutorServiceStrategy().setDefaultThreadPoolProfile(profile);
+ defaultIds.add(id);
+ } else {
+ context.getExecutorServiceStrategy().registerThreadPoolProfile(profile);
+ }
+ }
+ }
+
+ // use custom profiles defined in the CamelContext
+ if (getThreadPoolProfiles() != null && !getThreadPoolProfiles().isEmpty()) {
+ for (ThreadPoolProfileDefinition profile : getThreadPoolProfiles()) {
+ if (profile.isDefaultProfile()) {
+ LOG.info("Using custom default ThreadPoolProfile with id: " + profile.getId() + " and implementation: " + profile);
+ context.getExecutorServiceStrategy().setDefaultThreadPoolProfile(profile);
+ defaultIds.add(profile.getId());
+ } else {
+ context.getExecutorServiceStrategy().registerThreadPoolProfile(profile);
+ }
+ }
+ }
+
+ // validate at most one is defined
+ if (defaultIds.size() > 1) {
+ throw new IllegalArgumentException("Only exactly one default ThreadPoolProfile is allowed, was " + defaultIds.size() + " ids: " + defaultIds);
+ }
+ }
+
+ protected abstract void initBeanPostProcessor(T context);
+
+ /**
+ * Strategy to install all available routes into the context
+ */
+ protected void installRoutes() throws Exception {
+ List<RouteBuilder> builders = new ArrayList<RouteBuilder>();
+
+ // lets add route builders added from references
+ if (getBuilderRefs() != null) {
+ for (RouteBuilderDefinition builderRef : getBuilderRefs()) {
+ RouteBuilder builder = builderRef.createRouteBuilder(getContext());
+ if (builder != null) {
+ builders.add(builder);
+ } else {
+ // support to get the route here
+ RoutesBuilder routes = builderRef.createRoutes(getContext());
+ if (routes != null) {
+ this.builders.add(routes);
+ } else {
+ // Throw the exception that we can't find any build here
+ throw new CamelException("Cannot find any routes with this RouteBuilder reference: " + builderRef);
+ }
+ }
+ }
+ }
+
+ // install already configured routes
+ for (RoutesBuilder routeBuilder : this.builders) {
+ getContext().addRoutes(routeBuilder);
+ }
+
+ // install builders
+ for (RouteBuilder builder : builders) {
+ // Inject the annotated resource
+ postProcessBeforeInit(builder);
+ getContext().addRoutes(builder);
+ }
+ }
+
+ protected abstract void postProcessBeforeInit(RouteBuilder builder);
+
+ /**
+ * Strategy method to try find {@link org.apache.camel.builder.RouteBuilder} instances on the classpath
+ */
+ protected void findRouteBuilders() throws Exception {
+ PackageScanClassResolver resolver = getContext().getPackageScanClassResolver();
+ addPackageElementContentsToScanDefinition();
+
+ PackageScanDefinition packageScanDef = getPackageScan();
+ if (packageScanDef != null && packageScanDef.getPackages().size() > 0) {
+ // use package scan filter
+ PatternBasedPackageScanFilter filter = new PatternBasedPackageScanFilter();
+ // support property placeholders in include and exclude
+ for (String include : packageScanDef.getIncludes()) {
+ include = getContext().resolvePropertyPlaceholders(include);
+ filter.addIncludePattern(include);
+ }
+ for (String exclude : packageScanDef.getExcludes()) {
+ exclude = getContext().resolvePropertyPlaceholders(exclude);
+ filter.addExcludePattern(exclude);
+ }
+ resolver.addFilter(filter);
+
+ String[] normalized = normalizePackages(getContext(), packageScanDef.getPackages());
+ findRouteBuilders(normalized, builders);
+ }
+ }
+
+ protected abstract void findRouteBuilders(String[] normalized, List<RoutesBuilder> builders) throws Exception;
+
+ private void addPackageElementContentsToScanDefinition() {
+ PackageScanDefinition packageScanDef = getPackageScan();
+
+ if (getPackages() != null && getPackages().length > 0) {
+ if (packageScanDef == null) {
+ packageScanDef = new PackageScanDefinition();
+ setPackageScan(packageScanDef);
+ }
+
+ for (String pkg : getPackages()) {
+ packageScanDef.getPackages().add(pkg);
+ }
+ }
+ }
+
+ private String[] normalizePackages(T context, List<String> unnormalized) throws Exception {
+ List<String> packages = new ArrayList<String>();
+ for (String name : unnormalized) {
+ // it may use property placeholders
+ name = context.resolvePropertyPlaceholders(name);
+ name = ObjectHelper.normalizeClassName(name);
+ if (ObjectHelper.isNotEmpty(name)) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Using package: " + name + " to scan for RouteBuilder classes");
+ }
+ packages.add(name);
+ }
+ }
+ return packages.toArray(new String[packages.size()]);
+ }
+
+}
\ No newline at end of file
Added: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelEndpointFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelEndpointFactoryBean.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelEndpointFactoryBean.java (added)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelEndpointFactoryBean.java Fri May 28 07:52:33 2010
@@ -0,0 +1,97 @@
+package org.apache.camel.core.xml;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Endpoint;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.model.IdentifiedType;
+
+import static org.apache.camel.util.ObjectHelper.notNull;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class AbstractCamelEndpointFactoryBean extends IdentifiedType implements CamelContextAware {
+ @XmlAttribute
+ @Deprecated
+ private Boolean singleton = Boolean.FALSE;
+ @XmlAttribute
+ private String uri;
+ @XmlAttribute
+ private String camelContextId;
+ @XmlTransient
+ private CamelContext context;
+ @XmlTransient
+ private Endpoint endpoint;
+
+ public Object getObject() throws Exception {
+ if (endpoint == null || !endpoint.isSingleton()) {
+ if (context == null && camelContextId != null) {
+ context = getCamelContextWithId(camelContextId);
+ }
+
+ notNull(context, "context");
+ notNull(uri, "uri");
+
+ endpoint = context.getEndpoint(uri);
+ if (endpoint == null) {
+ throw new NoSuchEndpointException(uri);
+ }
+ }
+ return endpoint;
+ }
+
+ protected abstract CamelContext getCamelContextWithId(String camelContextId);
+
+ public Class getObjectType() {
+ return Endpoint.class;
+ }
+
+ public boolean isSingleton() {
+ return false;
+ }
+
+ public void setSingleton(boolean singleton) {
+ }
+
+ public CamelContext getCamelContext() {
+ return context;
+ }
+
+
+ /**
+ * Sets the context to use to resolve endpoints
+ *
+ * @param context the context used to resolve endpoints
+ */
+ public void setCamelContext(CamelContext context) {
+ this.context = context;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * Sets the URI to use to resolve the endpoint
+ *
+ * @param uri the URI used to set the endpoint
+ */
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public String getCamelContextId() {
+ return camelContextId;
+ }
+
+ public void setCamelContextId(String camelContextId) {
+ this.camelContextId = camelContextId;
+ }
+
+}
Added: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelProducerTemplateFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelProducerTemplateFactoryBean.java?rev=949127&view=auto
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelProducerTemplateFactoryBean.java (added)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelProducerTemplateFactoryBean.java Fri May 28 07:52:33 2010
@@ -0,0 +1,136 @@
+/**
+ * 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 org.apache.camel.core.xml;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Endpoint;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.impl.DefaultProducerTemplate;
+import org.apache.camel.model.IdentifiedType;
+import org.apache.camel.util.ServiceHelper;
+
+/**
+ * A factory for creating a new {@link org.apache.camel.ProducerTemplate}
+ * instance with a minimum of XML
+ *
+ * @version $Revision: 934375 $
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class AbstractCamelProducerTemplateFactoryBean extends IdentifiedType implements CamelContextAware {
+ @XmlTransient
+ private ProducerTemplate template;
+ @XmlAttribute(required = false)
+ private String defaultEndpoint;
+ @XmlAttribute
+ private String camelContextId;
+ @XmlTransient
+ private CamelContext camelContext;
+ @XmlAttribute
+ private Integer maximumCacheSize;
+
+ public void afterPropertiesSet() throws Exception {
+ if (camelContext == null && camelContextId != null) {
+ camelContext = getCamelContextWithId(camelContextId);
+ }
+ if (camelContext == null) {
+ throw new IllegalArgumentException("A CamelContext or a CamelContextId must be injected!");
+ }
+ }
+
+ protected abstract CamelContext getCamelContextWithId(String camelContextId);
+
+ public Object getObject() throws Exception {
+ CamelContext context = getCamelContext();
+ if (defaultEndpoint != null) {
+ Endpoint endpoint = context.getEndpoint(defaultEndpoint);
+ if (endpoint == null) {
+ throw new IllegalArgumentException("No endpoint found for URI: " + defaultEndpoint);
+ } else {
+ template = new DefaultProducerTemplate(context, endpoint);
+ }
+ } else {
+ template = new DefaultProducerTemplate(context);
+ }
+
+ // set custom cache size if provided
+ if (maximumCacheSize != null) {
+ template.setMaximumCacheSize(maximumCacheSize);
+ }
+
+ // must start it so its ready to use
+ ServiceHelper.startService(template);
+ return template;
+ }
+
+ public Class getObjectType() {
+ return DefaultProducerTemplate.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+ public void destroy() throws Exception {
+ ServiceHelper.stopService(template);
+ }
+
+ // Properties
+ // -------------------------------------------------------------------------
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ public void setCamelContext(CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ public String getDefaultEndpoint() {
+ return defaultEndpoint;
+ }
+
+ /**
+ * Sets the default endpoint URI used by default for sending message exchanges
+ */
+ public void setDefaultEndpoint(String defaultEndpoint) {
+ this.defaultEndpoint = defaultEndpoint;
+ }
+
+ public String getCamelContextId() {
+ return camelContextId;
+ }
+
+ public void setCamelContextId(String camelContextId) {
+ this.camelContextId = camelContextId;
+ }
+
+ public Integer getMaximumCacheSize() {
+ return maximumCacheSize;
+ }
+
+ public void setMaximumCacheSize(Integer maximumCacheSize) {
+ this.maximumCacheSize = maximumCacheSize;
+ }
+
+
+}