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.queue; 018 019 import java.util.Queue; 020 import java.util.concurrent.BlockingQueue; 021 import java.util.concurrent.TimeUnit; 022 import java.util.concurrent.atomic.AtomicBoolean; 023 024 import org.apache.camel.CamelContext; 025 import org.apache.camel.Processor; 026 import org.apache.camel.Exchange; 027 import org.apache.camel.impl.DefaultEndpoint; 028 import org.apache.camel.impl.DefaultExchange; 029 030 /** 031 * Represents a queue endpoint that uses a {@link BlockingQueue} 032 * object to process inbound exchanges. 033 * 034 * @org.apache.xbean.XBean 035 * @version $Revision: 519973 $ 036 */ 037 public class QueueEndpoint<E extends Exchange> extends DefaultEndpoint<E> { 038 private BlockingQueue<E> queue; 039 private org.apache.camel.queue.QueueEndpoint.Activation activation; 040 041 public QueueEndpoint(String uri, CamelContext container, BlockingQueue<E> queue) { 042 super(uri, container); 043 this.queue = queue; 044 } 045 046 public void onExchange(E exchange) { 047 queue.add(exchange); 048 } 049 050 public void setInboundProcessor(Processor<E> processor) { 051 // TODO lets start a thread to process inbound requests 052 // if we don't already have one 053 } 054 055 public E createExchange() { 056 // How can we create a specific Exchange if we are generic?? 057 // perhaps it would be better if we did not implement this. 058 return (E) new DefaultExchange(getContext()); 059 } 060 061 public Queue<E> getQueue() { 062 return queue; 063 } 064 065 class Activation implements Runnable { 066 AtomicBoolean stop = new AtomicBoolean(); 067 private Thread thread; 068 069 public void run() { 070 while(!stop.get()) { 071 E exchange=null; 072 try { 073 exchange = queue.poll(100, TimeUnit.MILLISECONDS); 074 } catch (InterruptedException e) { 075 break; 076 } 077 if( exchange !=null ) { 078 try { 079 getInboundProcessor().onExchange(exchange); 080 } catch (Throwable e) { 081 e.printStackTrace(); 082 } 083 } 084 } 085 } 086 087 public void start() { 088 thread = new Thread(this, getEndpointUri()); 089 thread.setDaemon(true); 090 thread.start(); 091 } 092 093 public void stop() throws InterruptedException { 094 stop.set(true); 095 thread.join(); 096 } 097 098 @Override 099 public String toString() { 100 return "Activation: "+getEndpointUri(); 101 } 102 } 103 104 @Override 105 protected void doActivate() { 106 activation = new Activation(); 107 activation.start(); 108 } 109 110 @Override 111 protected void doDeactivate() { 112 try { 113 activation.stop(); 114 activation=null; 115 } catch (InterruptedException e) { 116 throw new RuntimeException(e); 117 } 118 } 119 }