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 }