Basisklassen zum Modul jdk.httpserver
ulrich
2021-07-03 73b5b85c1c7caf1095ae004cb8efb7b73f360099
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
  http-base - Extensions to jdk.httpserver
  Copyright (C) 2021  Ulrich Hilger
 
  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as
  published by the Free Software Foundation, either version 3 of the
  License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Affero General Public License for more details.
 
  You should have received a copy of the GNU Affero General Public License
  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
package de.uhilger.httpserver.base.handler;
 
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
 * Der PatternDelegator delegiert HTTP-Aufrufe an HttpHandler, indem 
 * der URL des Aufrufs mit einem Muster verglichen wird. Zu einem bestimmten 
 * Muster passende URLs werden an den zum Muster hinterlegten HttpHandler 
 * weitergegeben.
 * 
 * Wird kein passendes Muster gefunden, reicht der PatternDelegator 
 * die Anfrage an den FileHandler weiter, wodurch - sofern vorhanden - die 
 * vom URL bezeichnete Ressource ausgeliefert wird.
 * 
 * @author Ulrich Hilger
 * @version 1, 29.06.2021
 */
public class PatternDelegator extends FileHandler {
  
  /** Der Logger dieser Klasse */
  private static final Logger logger = Logger.getLogger(PatternDelegator.class.getName());
  
  /** die HttpHandler, an die dieser Delegator passende Anfragen weitergibt */
  //private Map<String, HttpHandler> handlers;
  private Map<String, HandlerDescriptor> handlers;
 
  /**
   * Ein neues Objekt der Klasse PatternDelegator erzeugen
   */
  public PatternDelegator() {
    //super(absoluteDirectoryPathAndName);
    handlers = new HashMap();
  }
  
  /**
   * Diesem Delegator einen HttpHandler hinzufuegen
   * 
   * @param pattern  das Muster, das ein URL treffen muss, damit der hier 
   * hinzugefuegte Handler aufgerufen wird
   * @param handler  der Handler, an den dieser Delegator eine Anfrage 
   * delegiert, wenn das Muster passt
   */
  public void addHandler(String pattern, HandlerDescriptor handler) {
    handlers.put(pattern, handler);
  }
 
  /**
   * Einen HttpHandler von diesem Delegator entfernen
   * 
   * @param pattern  das Muster, das dem HttpHandler zugeordnet ist, der 
   * entfernt werden soll
   */
  public void removeHandler(String pattern) {
    handlers.remove(pattern);
  }
  
  /**
   * Eine HTTP-Anfrage ausfuehren, indem das Muster des URL mit den 
   * Mustern verglichen wird, die fuer diesen Delegator hinterlegt wurden 
   * und die Anfrage an den HttpHandler delegiert wird, dessen Aufrufmuster 
   * passt
   * 
   * @param exchange  das Objekt mit allen Infos zu Anfrage und Antwort
   * @throws IOException wenn etwas nicht geklappt hat
   */
  @Override
  public void handle(HttpExchange exchange) throws IOException {
    String path = exchange.getRequestURI().getPath();
    logger.fine("path: " + path);
    Set keys = handlers.keySet();
    Iterator<String> i = keys.iterator();
    boolean noMatch = true;
    while(i.hasNext() && noMatch) {
      String regex = i.next();
      logger.fine("regex: " + regex);
      if(path.matches(regex)) {
        try {
          noMatch = false;
          logger.fine("match");
          //HttpHandler handler = handlers.get(regex);
          HandlerDescriptor hd = handlers.get(regex);
          String handlerClass = hd.getHandlerClassName();
          Object o = Class.forName(handlerClass).getConstructors()[0].newInstance();
          if(o instanceof AttributeHandler) {
            AttributeHandler handler = (AttributeHandler) o;
            Map<String, String> attrs = hd.getAttributes();
            Iterator<String> it = attrs.keySet().iterator();
            while(it.hasNext()) {
              String key = it.next();
              String value = attrs.get(key);
              handler.setAttribute(key, value);
            }
            handler.handle(exchange);      
          } else if(o instanceof HttpHandler) {
            HttpHandler handler = (HttpHandler) o;
            handler.handle(exchange);      
          }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
          Logger.getLogger(PatternDelegator.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    }
    if(noMatch) {
      super.handle(exchange);
    }
  }
  
}