001: /*
002: * $Id: SimpleCallableJavaComponent.java 11379 2008-03-17 02:46:56Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.component;
012:
013: import org.mule.DefaultMuleEventContext;
014: import org.mule.VoidResult;
015: import org.mule.api.DefaultMuleException;
016: import org.mule.api.MuleEvent;
017: import org.mule.api.MuleException;
018: import org.mule.api.MuleMessage;
019: import org.mule.api.MuleRuntimeException;
020: import org.mule.api.component.JavaComponent;
021: import org.mule.api.component.LifecycleAdapter;
022: import org.mule.api.lifecycle.Callable;
023: import org.mule.api.lifecycle.Disposable;
024: import org.mule.api.lifecycle.Startable;
025: import org.mule.api.lifecycle.Stoppable;
026: import org.mule.api.model.ModelException;
027: import org.mule.api.object.ObjectFactory;
028: import org.mule.config.i18n.CoreMessages;
029: import org.mule.object.SingletonObjectFactory;
030: import org.mule.transformer.TransformerTemplate;
031:
032: import edu.emory.mathcs.backport.java.util.Collections;
033:
034: /**
035: * Simple {@link JavaComponent} implementation to be used when
036: * {@link LifecycleAdapter} is not required because i) the object instance implements
037: * {@link Callable} and so entry-point resolution is required and ii) nested-routers
038: * are not used.<br/> An {@link ObjectFactory} can be set but must return object
039: * instances that implement {@link Callable}. If one of the constructors that takes
040: * just a Class or the instance itself is used then the
041: * {@link SingletonObjectFactory} is used by default. <br/> This implementation
042: * replaces and improves on <code>OptimizedComponent</code>/<code>OptimizedMuleProxy</code>
043: */
044: public class SimpleCallableJavaComponent extends AbstractJavaComponent {
045:
046: private boolean started = false;
047: private boolean disposed = false;
048:
049: public SimpleCallableJavaComponent() {
050: // for spring
051: }
052:
053: /**
054: * Create an SimpleCallableJavaComponent instance using an object instance that
055: * implements {@link Callable}
056: *
057: * @param callable
058: */
059: public SimpleCallableJavaComponent(Callable callable) {
060: objectFactory = new SingletonObjectFactory(callable);
061: }
062:
063: /**
064: * Create an SimpleCallableJavaComponent instance using an object class. This
065: * class should implement {@link Callable}.
066: *
067: * @param callable
068: * @throws DefaultMuleException if the Class specified does not implement
069: * {@link Callable}
070: */
071: public SimpleCallableJavaComponent(Class callable)
072: throws DefaultMuleException {
073: if (!(Callable.class.isAssignableFrom(callable))) {
074: throw new DefaultMuleException(CoreMessages
075: .objectNotOfCorrectType(callable, Callable.class));
076: }
077: objectFactory = new SingletonObjectFactory(callable);
078: }
079:
080: public SimpleCallableJavaComponent(ObjectFactory objectFactory)
081: throws DefaultMuleException {
082: if (!(Callable.class.isAssignableFrom(objectFactory
083: .getObjectClass()))) {
084: throw new DefaultMuleException(CoreMessages
085: .objectNotOfCorrectType(objectFactory
086: .getObjectClass(), Callable.class));
087: }
088: this .objectFactory = objectFactory;
089: }
090:
091: protected void doStart() throws MuleException {
092: super .doStart();
093: if (Startable.class.isAssignableFrom(objectFactory
094: .getObjectClass())) {
095: try {
096: ((Startable) objectFactory.getInstance()).start();
097: } catch (Exception e) {
098: throw new ModelException(CoreMessages
099: .failedToStart("Service '" + service.getName()
100: + "'"), e);
101: }
102: }
103: }
104:
105: protected void doStop() throws MuleException {
106: super .doStop();
107: if (started
108: && Stoppable.class.isAssignableFrom(objectFactory
109: .getObjectClass())) {
110: try {
111: ((Stoppable) objectFactory.getInstance()).stop();
112: } catch (Exception e) {
113: throw new ModelException(CoreMessages
114: .failedToStop("Service '" + service.getName()
115: + "'"), e);
116: }
117: }
118: }
119:
120: protected void doDispose() {
121: super .doDispose();
122: if (Disposable.class.isAssignableFrom(objectFactory
123: .getObjectClass())) {
124: try {
125: ((Disposable) objectFactory.getInstance()).dispose();
126: } catch (Exception e) {
127: logger.error("Unable to dispose component instance", e);
128: }
129: }
130: }
131:
132: public Class getObjectType() {
133: if (objectFactory != null) {
134: return objectFactory.getObjectClass();
135: } else {
136: return Callable.class;
137: }
138: }
139:
140: protected LifecycleAdapter borrowComponentLifecycleAdaptor()
141: throws Exception {
142: // no-op
143: return null;
144: }
145:
146: protected void returnComponentLifecycleAdaptor(
147: LifecycleAdapter lifecycleAdapter) {
148: // no-op
149: }
150:
151: protected MuleMessage invokeComponentInstance(MuleEvent event)
152: throws Exception {
153: Object result = ((Callable) objectFactory.getInstance())
154: .onCall(new DefaultMuleEventContext(event));
155: if (result instanceof VoidResult) {
156: // This will rewire the current message
157: event.transformMessage();
158: return event.getMessage();
159: } else if (result != null) {
160: if (result instanceof MuleMessage) {
161: return (MuleMessage) result;
162: } else {
163: event
164: .getMessage()
165: .applyTransformers(
166: Collections
167: .singletonList(new TransformerTemplate(
168: new TransformerTemplate.OverwitePayloadCallback(
169: result))));
170: return event.getMessage();
171: }
172: } else {
173: return null;
174: }
175: }
176:
177: // @Override
178: public void setObjectFactory(ObjectFactory objectFactory) {
179: if (!(Callable.class.isAssignableFrom(objectFactory
180: .getObjectClass()))) {
181: throw new MuleRuntimeException(CoreMessages
182: .objectNotOfCorrectType(objectFactory
183: .getObjectClass(), Callable.class));
184: }
185: super.setObjectFactory(objectFactory);
186: }
187: }
|