View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.coap.resource;
21  
22  import java.io.UnsupportedEncodingException;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import org.apache.mina.api.IoSession;
27  import org.apache.mina.coap.CoapCode;
28  import org.apache.mina.coap.CoapMessage;
29  import org.apache.mina.coap.CoapOption;
30  import org.apache.mina.coap.CoapOptionType;
31  import org.apache.mina.coap.MessageType;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  /**
36   * The resource registry for the different {@link ResourceHandler}.
37   * 
38   * 
39   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
40   */
41  public class ResourceRegistry {
42  
43      private static final Logger LOG = LoggerFactory.getLogger(ResourceRegistry.class);
44  
45      private Map<String, ResourceHandler> handlers = new HashMap<String, ResourceHandler>();
46  
47      /**
48       * Register a new resource handler.
49       * 
50       * @param handler the halder to register.
51       */
52      public void register(ResourceHandler handler) {
53          handlers.put(handler.getPath(), handler);
54      }
55  
56      /**
57       * Response to a request : delegate it to the correct handler for the requested path. If not found generate 4.04
58       * CoAP errors. if .well-know/core requested : generate a discover page.
59       * 
60       * @param request the request ot serve
61       * @return the response
62       */
63      public CoapMessage respond(CoapMessage request, IoSession session) {
64          // find the URI
65          StringBuilder urlBuilder = new StringBuilder("");
66          for (CoapOption opt : request.getOptions()) {
67              if (opt.getType() == CoapOptionType.URI_PATH) {
68                  if (urlBuilder.length() > 0) {
69                      urlBuilder.append("/");
70                  }
71                  urlBuilder.append(new String(opt.getData()));
72              }
73          }
74  
75          String url = urlBuilder.toString();
76          LOG.debug("requested URL : {}", url);
77  
78          if (url.length() < 1) {
79              // 4.00 !
80              return new CoapMessage(1, MessageType.ACK, CoapCode.BAD_REQUEST.getCode(), request.getId(),
81                      request.getToken(), new CoapOption[] { new CoapOption(CoapOptionType.CONTENT_FORMAT,
82                              new byte[] { 0 }) }, "no URL !".getBytes());
83          }
84          if (".well-known/core".equalsIgnoreCase(url)) {
85              // discovery !
86              return new CoapMessage(1, MessageType.ACK, CoapCode.CONTENT.getCode(), request.getId(), request.getToken(),
87                      new CoapOption[] { new CoapOption(CoapOptionType.CONTENT_FORMAT, new byte[] { 40 }) },
88                      getDiscovery());
89          } else {
90              ResourceHandler handler = handlers.get(url);
91              if (handler == null) {
92                  // 4.04 !
93                  return new CoapMessage(1, MessageType.ACK, CoapCode.NOT_FOUND.getCode(), request.getId(),
94                          request.getToken(), new CoapOption[] { new CoapOption(CoapOptionType.CONTENT_FORMAT,
95                                  new byte[] { 0 }) }, "not found !".getBytes());
96              } else {
97                  CoapResponse response = handler.handle(request, session);
98                  return new CoapMessage(1, request.getType() == MessageType.CONFIRMABLE ? MessageType.ACK
99                          : MessageType.NON_CONFIRMABLE, response.getCode(), request.getId(), request.getToken(),
100                         response.getOptions(), response.getContent());
101             }
102         }
103     }
104 
105     private byte[] getDiscovery() {
106         StringBuilder b = new StringBuilder();
107         boolean first = true;
108         for (Map.Entry<String, ResourceHandler> e : handlers.entrySet()) {
109             // ex :</link1>;if="If1";rt="Type1 Type2";title="Link test resource",
110             if (first) {
111                 first = false;
112             } else {
113                 b.append(",");
114             }
115             ResourceHandler h = e.getValue();
116             b.append("</").append(h.getPath()).append(">");
117             if (h.getInterface() != null) {
118                 b.append(";if=\"").append(h.getInterface()).append("\"");
119             }
120             if (h.getResourceType() != null) {
121                 b.append(";rt=\"").append(h.getResourceType()).append("\"");
122             }
123             if (h.getTittle() != null) {
124                 b.append(";title=\"").append(h.getTittle()).append("\"");
125             }
126         }
127         try {
128             return b.toString().getBytes("UTF-8");
129         } catch (UnsupportedEncodingException e1) {
130             throw new IllegalStateException("no UTF-8 codec", e1);
131         }
132     }
133 }