001: // AdminServer.java
002: // $Id: AdminServer.java,v 1.38 2007/04/10 13:21:50 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1997.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigsaw.admin;
007:
008: import java.io.ByteArrayInputStream;
009: import java.io.ByteArrayOutputStream;
010: import java.io.IOException;
011: import java.io.PrintStream;
012:
013: import java.util.Enumeration;
014: import java.util.Hashtable;
015: import java.util.Vector;
016:
017: import org.w3c.util.ObservableProperties;
018:
019: import org.w3c.tools.resources.AbstractContainer;
020: import org.w3c.tools.resources.AttributeHolder;
021: import org.w3c.tools.resources.DummyResourceReference;
022: import org.w3c.tools.resources.FramedResource;
023: import org.w3c.tools.resources.ProtocolException;
024: import org.w3c.tools.resources.ReplyInterface;
025: import org.w3c.tools.resources.RequestInterface;
026: import org.w3c.tools.resources.Resource;
027: import org.w3c.tools.resources.ResourceContext;
028: import org.w3c.tools.resources.ResourceException;
029: import org.w3c.tools.resources.ResourceFilter;
030: import org.w3c.tools.resources.ResourceReference;
031: import org.w3c.tools.resources.ServerInterface;
032:
033: import org.w3c.www.mime.MimeType;
034:
035: import org.w3c.www.http.HTTP;
036: import org.w3c.www.http.HttpEntityMessage;
037: import org.w3c.www.http.HttpRequestMessage;
038:
039: import org.w3c.jigsaw.daemon.ServerHandler;
040: import org.w3c.jigsaw.daemon.ServerHandlerInitException;
041: import org.w3c.jigsaw.daemon.ServerHandlerManager;
042:
043: import org.w3c.jigsaw.http.ControlResource;
044: import org.w3c.jigsaw.http.HTTPException;
045: import org.w3c.jigsaw.http.Reply;
046: import org.w3c.jigsaw.http.Request;
047: import org.w3c.jigsaw.http.httpd;
048:
049: import org.w3c.jigsaw.filters.TEFilter;
050:
051: import org.w3c.jigsaw.auth.GenericAuthFilter;
052: import org.w3c.jigsaw.auth.RealmsCatalog;
053:
054: import org.w3c.tools.resources.ProtocolException;
055: import org.w3c.tools.resources.ResourceException;
056: import org.w3c.tools.resources.serialization.Serializer;
057:
058: class ServerHandlerManagerResource extends AbstractContainer {
059: ServerHandlerManager shm = null;
060: AdminServer as = null;
061:
062: public ServerInterface getServer() {
063: return as;
064: }
065:
066: public ResourceReference lookup(String name) {
067: ServerHandler handler = shm.lookupServerHandler(name);
068: if (handler != null) {
069: return handler.getConfigResource();
070: }
071: return null;
072: }
073:
074: /**
075: * Enumerates all the servers present, as advertised by the
076: * ServerHandlerManager.
077: * It adds "realms" and "control", fake resources of the admin server
078: */
079: public Enumeration enumerateResourceIdentifiers(boolean all) {
080: String name;
081: Vector v = new Vector();
082: Enumeration e = shm.enumerateServerHandlers();
083: while (e.hasMoreElements()) {
084: name = (String) e.nextElement();
085: if (!(shm.lookupServerHandler(name) instanceof AdminServer)) {
086: v.addElement(name);
087: }
088: }
089: v.addElement("realms");
090: v.addElement("control");
091: return v.elements();
092: }
093:
094: public ResourceReference createDefaultResource(String name) {
095: // This should in fact create a new server handler
096: return null;
097: }
098:
099: public void registerResource(String name, Resource child,
100: Hashtable defs) {
101: throw new RuntimeException("Can't register resource there !");
102: }
103:
104: public void delete(String name) {
105: throw new RuntimeException("no delete supported");
106: }
107:
108: ServerHandlerManagerResource(AdminServer as,
109: ServerHandlerManager shm) {
110: this .as = as;
111: this .shm = shm;
112: }
113: }
114:
115: public class AdminServer extends httpd {
116: protected ResourceBroker broker = null;
117: protected ServerHandlerManager shm = null;
118: protected AdminWriter writer = null;
119: protected AbstractContainer root = null;
120: protected ResourceReference rr_root = null;
121: protected ControlResource controlConfig = null;
122: protected ResourceReference rr_controlConfig = null;
123: protected GenericAuthFilter auth = null;
124: protected Serializer serializer = null;
125: protected ResourceFilter filters[] = null;
126:
127: /**
128: * The realm catalog of the admin server, hardcoded as "adminRealms.db"
129: */
130:
131: protected RealmsCatalog realms = null;
132: protected ResourceReference rr_realms = null;
133:
134: private void initializeRealmsCatalog() {
135: this .realms = new RealmsCatalog(new ResourceContext(
136: getDefaultContext()), "adminRealms.db");
137: }
138:
139: public RealmsCatalog getRealmsCatalog() {
140: if (realms == null) {
141: initializeRealmsCatalog();
142: }
143: return realms;
144: }
145:
146: protected String getBanner() {
147: return "JigAdmin[2.2.6]";
148: }
149:
150: public ResourceReference getConfigResource() {
151: return getRootReference();
152: }
153:
154: public ResourceReference getRealmCatalogResource() {
155: if (rr_realms == null)
156: rr_realms = new DummyResourceReference(getRealmsCatalog());
157: return rr_realms;
158: }
159:
160: public ResourceReference getControlResource() {
161: if (rr_controlConfig == null) {
162: controlConfig = new ControlResource(this );
163: rr_controlConfig = new DummyResourceReference(controlConfig);
164: }
165: return rr_controlConfig;
166: }
167:
168: /**
169: * Load the remote Root.
170: * @param request The incomming request.
171: * @exception org.w3c.tools.resources.ProtocolException if a protocol
172: * error occurs.
173: */
174: public Reply remoteLoadRoot(Request request)
175: throws ProtocolException {
176: // Dump the root resource:
177: ByteArrayOutputStream bout = new ByteArrayOutputStream();
178: try {
179: writer.writeResource(root, bout);
180: } catch (IOException ex) {
181: System.out.println(ex.getMessage());
182: ex.printStackTrace();
183: throw new HTTPException("unable to dump root");
184: } catch (Exception ex) {
185: System.out.println(ex.getMessage());
186: ex.printStackTrace();
187: throw new HTTPException("unable to dump root: "
188: + ex.getMessage());
189: }
190: byte bits[] = bout.toByteArray();
191: // Setup the reply:
192: Reply reply = request.makeReply(HTTP.OK);
193: reply.setStream(new ByteArrayInputStream(bits));
194: reply.setContentLength(bits.length);
195: reply.setContentType(AdminContext.conftype);
196: return reply;
197: }
198:
199: /**
200: * Perform the request
201: * @param req the request.
202: * @exception ProtocolException if a protocol error occurs
203: * @exception ResourceException if a server error occurs
204: */
205: public ReplyInterface perform(RequestInterface req)
206: throws ProtocolException, ResourceException {
207: Request request = (Request) req;
208: Reply reply = null;
209: auth.authenticate(request);
210: //ingoing filters
211: for (int i = 0; i < filters.length; i++) {
212: reply = (Reply) filters[i].ingoingFilter(req);
213: if (reply != null)
214: return reply;
215: }
216: // Maybe that's one of the methods we handle straight ?
217: String mth = request.getMethod();
218: if (mth.equals("LOAD-ROOT")) {
219: reply = remoteLoadRoot(request);
220: } else {
221: // Ok, that's targeted toward a specific target resource:
222: try {
223: reply = (Reply) broker.perform(request);
224: } catch (org.w3c.tools.resources.ProtocolException ex) {
225: throw new HTTPException(ex);
226: }
227: }
228: //outgoing filters
229: for (int i = filters.length - 1; i > -1; i--) {
230: Reply rep = (Reply) filters[i].outgoingFilter(req, reply);
231: if (rep != null)
232: return rep;
233: }
234: return reply;
235: }
236:
237: public FramedResource getRoot() {
238: return root;
239: }
240:
241: public ResourceReference getRootReference() {
242: if (rr_root == null)
243: rr_root = new DummyResourceReference(root);
244: return rr_root;
245: }
246:
247: protected void initializeAuth() {
248: Hashtable defs = null;
249: defs = new Hashtable(3);
250: defs.put("identifier", "auth-frame");
251: root.registerFrame(auth, defs);
252: auth.setValue("realm", "JigAdmin");
253: }
254:
255: protected void addFilter(ResourceFilter filter, Hashtable defs) {
256: filter.initialize(defs);
257: if (filters == null) {
258: filters = new ResourceFilter[1];
259: filters[0] = filter;
260: } else {
261: int len = filters.length;
262: ResourceFilter nfilters[] = new ResourceFilter[len + 1];
263: System.arraycopy(filters, 0, nfilters, 0, len);
264: nfilters[len] = filter;
265: filters = nfilters;
266: }
267: }
268:
269: /**
270: * Initialize the Server
271: * @exception ServerHandlerInitException if it can't be initialized
272: */
273: public void initialize(ServerHandlerManager shm, String identifier,
274: ObservableProperties props)
275: throws ServerHandlerInitException {
276: super .initialize(shm, identifier, props);
277: // Create our only resource:
278: this .shm = shm;
279: writer = new AdminWriter();
280: broker = new ResourceBroker(shm, this , writer);
281: root = new ServerHandlerManagerResource(this , shm);
282: auth = new GenericAuthFilter();
283: serializer = new org.w3c.tools.resources.serialization.xml.XMLSerializer();
284: initializeAuth();
285: TEFilter tefilter = new TEFilter();
286: Hashtable defs = new Hashtable(2);
287: defs.put("identifier", "tefilter");
288: String mimes[] = { AdminContext.conftype.toString() };
289: defs.put("mime-types", mimes);
290: // FIXME, we should be able to set/change the way filters are added
291: // for better security and/or flexibility
292: addFilter(tefilter, defs);
293: }
294:
295: public AdminServer() {
296: }
297: }
|