001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.javaspace;
018    
019    import java.io.ByteArrayInputStream;
020    import java.io.ByteArrayOutputStream;
021    import java.io.File;
022    import java.io.ObjectInputStream;
023    import java.io.ObjectOutputStream;
024    import java.rmi.server.UID;
025    
026    import net.jini.core.entry.Entry;
027    import net.jini.core.lease.Lease;
028    import net.jini.core.transaction.Transaction;
029    import net.jini.space.JavaSpace;
030    
031    import org.apache.camel.Exchange;
032    import org.apache.camel.Producer;
033    import org.apache.camel.component.bean.BeanInvocation;
034    import org.apache.camel.impl.DefaultProducer;
035    import org.apache.camel.util.ExchangeHelper;
036    import org.apache.commons.logging.Log;
037    import org.apache.commons.logging.LogFactory;
038    
039    /**
040     * A {@link Producer} implementation for JavaSpaces
041     * 
042     * @version $Revision: 15488 $
043     */
044    public class JavaSpaceProducer extends DefaultProducer {
045        private static final transient Log LOG = LogFactory.getLog(JavaSpaceProducer.class);
046    
047        private final boolean transactional;
048        private final long transactionTimeout;
049        private JavaSpace javaSpace;
050        private TransactionHelper transactionHelper;
051    
052        public JavaSpaceProducer(JavaSpaceEndpoint endpoint) throws Exception {
053            super(endpoint);
054            this.transactional = endpoint.isTransactional();
055            this.transactionTimeout = endpoint.getTransactionTimeout();
056        }
057    
058        public void process(Exchange exchange) throws Exception {
059            Entry entry;
060            Object body = exchange.getIn().getBody();
061    
062            if (!(body instanceof Entry)) {
063                entry = new InEntry();
064    
065                if (body instanceof BeanInvocation) {
066                    ((InEntry) entry).correlationId = (new UID()).toString();
067                }
068    
069                if (body instanceof byte[]) {
070                    ((InEntry) entry).binary = true;
071                    ((InEntry) entry).buffer = (byte[]) body;
072                } else {
073                    ((InEntry) entry).binary = false;
074                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
075                    ObjectOutputStream oos = new ObjectOutputStream(bos);
076                    oos.writeObject(body);
077                    ((InEntry) entry).buffer = bos.toByteArray();
078                }
079            } else {
080                entry = (Entry) body;
081            }
082    
083            if (entry == null) {
084                LOG.warn("No payload for exchange: " + exchange);
085            } else {
086                Transaction tnx = null;
087                if (transactionHelper != null) {
088                    tnx = transactionHelper.getJiniTransaction(transactionTimeout).transaction;
089                }
090                if (LOG.isDebugEnabled()) {
091                    LOG.debug("Writing body : " + entry);
092                }
093                javaSpace.write(entry, tnx, Lease.FOREVER);
094    
095                if (ExchangeHelper.isOutCapable(exchange)) {
096                    OutEntry tmpl = new OutEntry();
097                    tmpl.correlationId = ((InEntry) entry).correlationId;
098    
099                    OutEntry replyCamelEntry = null;
100                    while (replyCamelEntry == null) {
101                        replyCamelEntry = (OutEntry) javaSpace.take(tmpl, tnx, 100);
102                    }
103    
104                    Object obj;
105                    if (replyCamelEntry.binary) {
106                        obj = replyCamelEntry.buffer;
107                    } else {
108                        ByteArrayInputStream bis = new ByteArrayInputStream(replyCamelEntry.buffer);
109                        ObjectInputStream ois = new ObjectInputStream(bis);
110                        obj = ois.readObject();
111                    }
112                    exchange.getOut().setBody(obj);
113                }
114                if (tnx != null) {
115                    tnx.commit();
116                }
117            }
118        }
119    
120        @Override
121        protected void doStart() throws Exception {
122            // TODO: There should be a switch to enable/disable using this security hack
123            Utility.setSecurityPolicy("policy.all", "policy_producer.all");
124            javaSpace = JiniSpaceAccessor.findSpace(((JavaSpaceEndpoint) this.getEndpoint()).getRemaining(),
125                    ((JavaSpaceEndpoint) this.getEndpoint()).getSpaceName());
126            if (transactional) {
127                transactionHelper = TransactionHelper.getInstance(((JavaSpaceEndpoint) this.getEndpoint()).getRemaining());
128            }
129            (new File("policy_producer.all")).delete();
130        }
131    
132        @Override
133        protected void doStop() throws Exception {
134        }
135    
136    }