| /** |
| * 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.coap; |
| |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.apache.camel.Message; |
| import org.eclipse.californium.core.CoapResource; |
| import org.eclipse.californium.core.coap.CoAP.ResponseCode; |
| import org.eclipse.californium.core.coap.MediaTypeRegistry; |
| import org.eclipse.californium.core.coap.OptionSet; |
| import org.eclipse.californium.core.network.Exchange; |
| import org.eclipse.californium.core.server.resources.CoapExchange; |
| import org.eclipse.californium.core.server.resources.Resource; |
| |
| final class CamelCoapResource extends CoapResource { |
| private final Map<String, CoAPConsumer> consumers = new ConcurrentHashMap<>(); |
| private final List<CamelCoapResource> possibles; |
| |
| CamelCoapResource(String name, CoAPConsumer consumer) { |
| super(name); |
| consumers.put(consumer.getCoapEndpoint().getCoapMethod(), consumer); |
| possibles = null; |
| } |
| |
| private CamelCoapResource(String name, List<CamelCoapResource> possibles) { |
| super(name); |
| this.possibles = possibles; |
| } |
| |
| void addConsumer(CoAPConsumer consumer) { |
| consumers.put(consumer.getCoapEndpoint().getCoapMethod(), consumer); |
| } |
| |
| @Override |
| public Resource getChild(String name) { |
| if (possibles != null) { |
| //FIXME - find which might work... |
| } |
| Resource child = super.getChild(name); |
| if (child == null) { |
| final List<CamelCoapResource> possibles = new LinkedList<>(); |
| for (Resource r : getChildren()) { |
| if (r.getName().startsWith("{") && r.getName().endsWith("}")) { |
| possibles.add((CamelCoapResource)r); |
| } |
| } |
| if (possibles.size() == 1) { |
| return possibles.get(0); |
| } |
| if (!possibles.isEmpty()) { |
| return new CamelCoapResource(name, possibles); |
| } |
| } |
| return child; |
| } |
| @Override |
| public void handleRequest(Exchange exchange) { |
| org.apache.camel.Exchange camelExchange = null; |
| CoAPConsumer consumer = null; |
| if (possibles != null) { |
| consumers.putAll(possibles.get(0).consumers); |
| } |
| CoapExchange cexchange = new CoapExchange(exchange, this); |
| try { |
| consumer = consumers.get(exchange.getRequest().getCode().name()); |
| if (consumer == null) { |
| consumer = consumers.get("*"); |
| } |
| |
| camelExchange = consumer.getEndpoint().createExchange(); |
| consumer.createUoW(camelExchange); |
| |
| OptionSet options = exchange.getRequest().getOptions(); |
| for (String s : options.getUriQuery()) { |
| int i = s.indexOf('='); |
| if (i == -1) { |
| camelExchange.getIn().setHeader(s, ""); |
| } else { |
| camelExchange.getIn().setHeader(s.substring(0, i), s.substring(i + 1)); |
| } |
| } |
| |
| if (options.hasContentFormat()) { |
| String mt = MediaTypeRegistry.toString(options.getContentFormat()); |
| camelExchange.getIn().setHeader(org.apache.camel.Exchange.CONTENT_TYPE, mt); |
| } |
| |
| List<String> path = exchange.getRequest().getOptions().getUriPath(); |
| LinkedList<Resource> resources = new LinkedList<>(); |
| Resource r = this; |
| while (r != null) { |
| resources.push(r); |
| r = r.getParent(); |
| } |
| if (resources.getFirst().getName().isEmpty()) { |
| resources.removeFirst(); |
| } |
| int res = 0; |
| while (!resources.isEmpty() && res < path.size()) { |
| r = resources.removeFirst(); |
| if (r.getName().charAt(0) == '{' && r.getName().charAt(r.getName().length() - 1) == '}') { |
| String n = r.getName().substring(1, r.getName().length() - 1); |
| camelExchange.getIn().setHeader(n, path.get(res)); |
| } |
| res++; |
| } |
| |
| byte bytes[] = exchange.getCurrentRequest().getPayload(); |
| camelExchange.getIn().setBody(bytes); |
| |
| consumer.getProcessor().process(camelExchange); |
| Message target = camelExchange.hasOut() ? camelExchange.getOut() : camelExchange.getIn(); |
| |
| int format = MediaTypeRegistry.parse(target.getHeader(org.apache.camel.Exchange.CONTENT_TYPE, String.class)); |
| cexchange.respond(ResponseCode.CONTENT, target.getBody(byte[].class), format); |
| |
| } catch (Exception e) { |
| cexchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, e.getMessage()); |
| } finally { |
| if (camelExchange != null) { |
| consumer.doneUoW(camelExchange); |
| } |
| } |
| } |
| } |