Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / jigsaw / admin / BrokerFrame.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/admin/BrokerFrame.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/admin/BrokerFrame.java
new file mode 100644 (file)
index 0000000..f4aa2bc
--- /dev/null
@@ -0,0 +1,627 @@
+// BrokerFrame.java\r
+// $Id: BrokerFrame.java,v 1.2 2010/06/15 17:53:08 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1997.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.admin;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import java.util.Hashtable;\r
+import java.util.StringTokenizer;\r
+\r
+import java.util.zip.GZIPInputStream;\r
+\r
+import org.w3c.jigsaw.daemon.ServerHandler;\r
+import org.w3c.jigsaw.daemon.ServerHandlerManager;\r
+\r
+import org.w3c.tools.resources.AttributeHolder;\r
+import org.w3c.tools.resources.ContainerInterface;\r
+import org.w3c.tools.resources.DirectoryResource;\r
+import org.w3c.tools.resources.FramedResource;\r
+import org.w3c.tools.resources.InvalidResourceException;\r
+import org.w3c.tools.resources.LookupResult;\r
+import org.w3c.tools.resources.LookupState;\r
+import org.w3c.tools.resources.MultipleLockException;\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.Resource;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.tools.resources.ResourceFrame;\r
+import org.w3c.tools.resources.ResourceReference;\r
+\r
+import org.w3c.www.mime.MimeType;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpEntityMessage;\r
+import org.w3c.www.http.HttpMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+import org.w3c.jigsaw.http.Client;\r
+import org.w3c.jigsaw.http.HTTPException;\r
+import org.w3c.jigsaw.http.Reply;\r
+import org.w3c.jigsaw.http.Request;\r
+\r
+import org.w3c.jigsaw.frames.HTTPFrame;\r
+\r
+import org.w3c.tools.resources.ProtocolException;\r
+import org.w3c.tools.resources.ResourceException;\r
+import org.w3c.tools.resources.serialization.ResourceDescription;\r
+import org.w3c.tools.resources.serialization.AttributeDescription;\r
+\r
+public class BrokerFrame extends HTTPFrame {\r
+\r
+    class LookupFrameState {\r
+       private int     index ;\r
+       private String  components[] ;\r
+\r
+       void parseQuery(String query) {\r
+           StringTokenizer st = new StringTokenizer(query, "?");\r
+           int nbTokens = st.countTokens();\r
+           components = new String[nbTokens];\r
+           for (int i = 0 ; i < nbTokens ; i++)\r
+               components[i] = st.nextToken();\r
+           index = 0;\r
+       }\r
+\r
+       public boolean hasMoreComponents() {\r
+           return index < components.length ;\r
+       }\r
+\r
+       public final String getNextComponent() {\r
+           return components[index++] ;\r
+       }\r
+\r
+       LookupFrameState (String query) {\r
+           parseQuery(query);\r
+       }\r
+    }\r
+\r
+    protected ResourceBroker broker = null;\r
+\r
+    public void registerResource(FramedResource resource) {\r
+       super.registerResource(resource);\r
+       if (resource instanceof ResourceBroker)\r
+           broker = (ResourceBroker) resource;\r
+    }\r
+\r
\r
+    /**\r
+     * The object that knows how to write the admin protocol.\r
+     */\r
+    protected AdminWriter writer = null;\r
+\r
+    /**\r
+     * The ServerHandlerManager we export.\r
+     */\r
+    protected ServerHandlerManager shm = null;\r
+    /**\r
+     * The controlling ServerHandler.\r
+     */\r
+    protected AdminServer admin = null;\r
+\r
+    /**\r
+     * Trigger an HTTP exception.\r
+     * @param request The request we couldn't fulfill.\r
+     * @param msg The error message.\r
+     * @exception ProtocolException Always thrown.\r
+     */\r
+\r
+    protected void error(Request request, String msg) \r
+       throws ProtocolException\r
+    {\r
+       Reply reply = request.makeReply(HTTP.INTERNAL_SERVER_ERROR);\r
+       reply.setContent(msg);\r
+       throw new HTTPException(reply);\r
+    }\r
+\r
+    protected Reply okReply(Request request, byte bits[]) {\r
+       Reply reply = request.makeReply(HTTP.OK);\r
+       reply.setContentType(AdminContext.conftype);\r
+       if ( bits != null ) {\r
+           ByteArrayInputStream in = new ByteArrayInputStream(bits);\r
+           reply.setContentLength(bits.length);\r
+           reply.setStream(in);\r
+       }\r
+       return reply;\r
+    }\r
+\r
+    protected Reply okReply(Request request) {\r
+       return okReply(request, null);\r
+    }\r
+\r
+    /**\r
+     * Check that request incomming content type.\r
+     * @param request The request to check.\r
+     * @exception ProtocolException If the request type doesn't match admin.\r
+     */\r
+\r
+    protected void checkContentType(Request request) \r
+       throws ProtocolException\r
+    {\r
+       if ( request.getContentType().match(AdminContext.conftype) < 0 ) \r
+           error(request, "invalid MIME type: "+request.getContentType());\r
+    }\r
+\r
+    /**\r
+     * Get a data input stream out of that request input stream\r
+     * @param request The request to get data from.\r
+     * @exception ProtocolException If we couldn't get the request's content.\r
+     * @return A DataInputStream instance to read the request's content.\r
+     */\r
+\r
+    protected InputStream getInputStream(Request request) \r
+       throws ProtocolException\r
+    {\r
+       // How fun HTTP/1.1 is, allowing us to double the network traffic :-(\r
+       // If this is a 1.1 request, send a 100 continue:\r
+       Client client = request.getClient();\r
+       if ( client != null ) {\r
+           try {\r
+               client.sendContinue();\r
+           } catch (IOException ex) {\r
+               throw new HTTPException(ex.getMessage());\r
+           }\r
+       }\r
+       // Now, only, get the data:\r
+       try {\r
+           if (request.hasTransferEncoding("gzip"))\r
+               return new GZIPInputStream(request.getInputStream());\r
+           else\r
+               return request.getInputStream();\r
+       } catch (IOException ex) {\r
+           error(request, "invalid request");\r
+       }\r
+       // not reached:\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * Lookup the target of the given request.\r
+     * @param request The request whose target is to be fetched.\r
+     * @return A Resource instance.\r
+     * @exception ProtocolException If the resource couldn't be located.\r
+     */\r
+\r
+    public ResourceReference lookup(Request request) \r
+       throws ProtocolException\r
+    {\r
+       // Create lookup state and get rid of root resource requests:\r
+       LookupState   ls = null;\r
+       try {\r
+           ls = new LookupState(request);\r
+       } catch (org.w3c.tools.resources.ProtocolException ex) {\r
+           ex.printStackTrace();\r
+           throw new HTTPException(ex);\r
+       }\r
+       LookupResult  lr = new LookupResult(null);\r
+       ResourceReference rr = null; // cr\r
+       ls.markInternal();\r
+       if ( ! ls.hasMoreComponents() ) \r
+           return admin.getRootReference();\r
+       // Lookup the target resource:\r
+       String name = ls.getNextComponent();\r
+       ServerHandler sh = shm.lookupServerHandler(name);\r
+       if ( sh == null ) {\r
+           if(name.equals("realms")) {\r
+               rr = admin.getRealmCatalogResource();\r
+           } else if (name.equals("control")) {\r
+               rr = admin.getControlResource();\r
+           } else {\r
+               error(request, "unknown server handler");\r
+           }\r
+       } else {\r
+           // Lookup that resource, from the config resource of that server:\r
+           rr = sh.getConfigResource();\r
+       }\r
+       if ( rr != null ) {\r
+           ResourceReference rr_temp = null;\r
+           while ( ls.hasMoreComponents() ) {\r
+               try {\r
+                   if (rr == null)\r
+                       error(request, "url too long");\r
+                   Resource r = rr.lock();\r
+                   if ( ! ( r instanceof ContainerInterface) )\r
+                       error(request, "url too long");\r
+                   rr_temp = ((ContainerInterface) r).lookup(\r
+                                                      ls.getNextComponent());\r
+               } catch (InvalidResourceException ex) {\r
+                   error(request, "unable to restore resource");\r
+               } finally {\r
+                   rr.unlock();\r
+                   rr = rr_temp;\r
+               }\r
+           }\r
+           if ( rr == null )\r
+               error(request, "unknown resource");\r
+           String query = request.getQueryString();\r
+           if ( query != null ) {\r
+               try {\r
+                   Resource r = rr.lock();\r
+                   // Querying a frame !\r
+                   if ( ! (r instanceof FramedResource) )\r
+                       error(request, "not a framed resource");\r
+               } catch (InvalidResourceException ex) {\r
+                   error(request, "unable to restore resource");\r
+               } finally {\r
+                   rr.unlock();\r
+               }\r
+\r
+               //search the right frame\r
+               LookupFrameState lfs = new LookupFrameState(query);\r
+       \r
+               String frameName = null;\r
+               ResourceReference the_rrf   = rr; \r
+               ResourceReference[] rra = null;   \r
+\r
+               while (lfs.hasMoreComponents()) {\r
+\r
+                   try {\r
+                       rra = ((FramedResource) \r
+                              the_rrf.lock()).getFramesReference();\r
+                       if (rra == null)\r
+                           error(request, "unknown frame");\r
+                   } catch (InvalidResourceException ex) {\r
+                       error(request, ex.getMessage());\r
+                   } finally {\r
+                       the_rrf.unlock();\r
+                   }\r
+                   the_rrf = null;\r
+                   frameName = lfs.getNextComponent();\r
+                   ResourceReference rrf   = null; \r
+                   ResourceFrame     frame = null;\r
+\r
+                   for (int i = 0 ; i < rra.length ; i++) {\r
+                       rrf = rra[i];\r
+                       try {\r
+                           frame = (ResourceFrame) rrf.lock();\r
+                           if (frame.getIdentifier().equals(frameName)) {\r
+                               the_rrf = rrf;\r
+                               break;\r
+                           }\r
+                       } catch (InvalidResourceException ex) {\r
+                           error(request, ex.getMessage());\r
+                       } finally {\r
+                           rrf.unlock();\r
+                       }\r
+                   }\r
+                   if (the_rrf == null)\r
+                       error(request,"unknown frame");\r
+               }\r
+       \r
+               return the_rrf;\r
+           } else {\r
+               // Emit back this resource (after a check):\r
+               return rr;\r
+           }\r
+       }\r
+       error(request, "unknown resource");\r
+       // not reached\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * Set a set of attribute values for the target resource.\r
+     * @param request The request to handle.\r
+     * @return A Reply instance.\r
+     * @exception ProtocolException If some error occurs.\r
+     */\r
+\r
+    public Reply remoteSetValues(Request request) \r
+       throws ProtocolException\r
+    {\r
+       InputStream in = getInputStream(request);\r
+       //Get the target resource to act on:\r
+       ResourceReference   rr    = lookup(request);\r
+       try {\r
+           Resource r = rr.lock();\r
+           ResourceDescription descr = \r
+               AdminReader.readResourceDescription(in);\r
+           AttributeDescription attrs[] = descr.getAttributeDescriptions();\r
+           for (int i = 0 ; i < attrs.length ; i++) {\r
+               AttributeDescription ad = attrs[i];\r
+               r.setValue(ad.getName(), ad.getValue());\r
+           }\r
+       } catch (InvalidResourceException irex) {\r
+           irex.printStackTrace();\r
+           error(request, "Invalid resource");\r
+       } catch (IOException ioex) {\r
+           error(request, "bad request");\r
+       } catch (AdminProtocolException apex) {\r
+           error(request, apex.getMessage());\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // All the changes done, return OK:\r
+       return okReply(request);\r
+    }\r
+\r
+    /**\r
+     * Return a resource back to the client.\r
+     * @param request The request to handle.\r
+     * @return A Reply instance.\r
+     * @exception ProtocolException If some error occurs.\r
+     */\r
+\r
+    public Reply remoteLoadResource(Request request) \r
+       throws ProtocolException\r
+    {\r
+       ResourceReference rr = lookup(request);\r
+\r
+       // This request has no content\r
+       ByteArrayOutputStream bout   = new ByteArrayOutputStream();\r
+\r
+       try {\r
+           Resource r = rr.lock();\r
+           writer.writeResource(r, bout);\r
+       } catch (IOException ex) {\r
+           error(request, "bad request");\r
+       } catch (InvalidResourceException ex) {\r
+           error(request, "Invalid resource");\r
+       } catch (AdminProtocolException ex) {\r
+           error(request, ex.getMessage());\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // Setup the reply:\r
+       return okReply(request, bout.toByteArray());\r
+    }\r
+\r
+    public Reply remoteRegisterFrame(Request request) \r
+       throws ProtocolException\r
+    {\r
+       ResourceReference rr = lookup(request);\r
+       try {\r
+           Resource r = rr.lock();\r
+           if ( ! ( r instanceof FramedResource) )\r
+               error(request, "can't add frame to non-framed resource");\r
+           // Handle the request:\r
+           try {\r
+               InputStream in  = getInputStream(request);\r
+               ResourceDescription rd = \r
+                   AdminReader.readResourceDescription(in);\r
+               String cls = rd.getClassName();\r
+               String id  = rd.getIdentifier();\r
+               // Create the frame:\r
+               ResourceFrame frame = null;\r
+               try {\r
+                   frame = (ResourceFrame) Class.forName(cls).newInstance();\r
+                   //Added by Jeff Huang\r
+                   //TODO: FIXIT\r
+               } catch (Exception ex) {\r
+                   error(request, "invalid frame class "+cls);\r
+               }\r
+               // Register the frame:\r
+               Hashtable defs = new Hashtable(3);\r
+               if ((id != null) && ! id.equals("") ) {\r
+                   defs.put("identifier", id);\r
+               }\r
+               ((FramedResource) r).registerFrame(frame, defs);\r
+               // Send back the whole resource (inclding new frame):\r
+               ByteArrayOutputStream bout = new ByteArrayOutputStream();\r
+               writer.writeResource(frame, bout);\r
+               return okReply(request, bout.toByteArray());\r
+           } catch (IOException ioex) {\r
+               error(request, "bad request");\r
+           } catch (AdminProtocolException apex) {\r
+               error(request, apex.getMessage());\r
+           }\r
+       } catch (InvalidResourceException irex) {\r
+           error(request, "invalid resource");\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // not reached:\r
+       return null;\r
+    }\r
+\r
+    public Reply remoteUnregisterFrame(Request request) \r
+       throws ProtocolException\r
+    {\r
+       ResourceReference rr = lookup(request);\r
+       try{\r
+           Resource r = rr.lock();\r
+           if(!(r instanceof FramedResource)) {\r
+               error(request, "Can't unregister frames from a non-framed" +\r
+                     " resource");\r
+           }\r
+           try {\r
+               InputStream in = getInputStream(request);\r
+               ResourceDescription rd = \r
+                   AdminReader.readResourceDescription(in);\r
+               String identifier  = rd.getIdentifier();                \r
+               // find the indentifier\r
+               ResourceFrame f[] = ((FramedResource) r).getFrames();\r
+               for (int i = 0 ; i < f.length ; i++)\r
+                   if (f[i].getIdentifier().equals(identifier)) {\r
+                       ((FramedResource) r).unregisterFrame(f[i]);\r
+                       return okReply(request);\r
+                   }\r
+               error(request, "Frame " + identifier + " not registered");\r
+           } catch (IOException ex) {\r
+               error(request, "bad request");\r
+           } catch (AdminProtocolException apex) {\r
+               error(request, apex.getMessage());\r
+           }\r
+       } catch (InvalidResourceException ex2) {\r
+           error(request, "invalid resource");\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // Not reached\r
+       return null;\r
+    }\r
+\r
+    public Reply remoteRegisterResource(Request request) \r
+       throws ProtocolException\r
+    {\r
+       // Check target resource class:\r
+       ResourceReference rr = lookup(request);\r
+       try {\r
+           Resource r = rr.lock();\r
+           if ( ! ( r instanceof ContainerInterface) )\r
+               error(request, "can't add child in non-container");\r
+           // Handle request:\r
+           try {\r
+               InputStream in = getInputStream(request);\r
+               ResourceDescription rd = \r
+                   AdminReader.readResourceDescription(in);\r
+               String cls = rd.getClassName();\r
+               String id  = rd.getIdentifier();\r
+               // Create the resource:\r
+               Resource child = null;\r
+               try {\r
+                   child = (Resource) Class.forName(cls).newInstance();\r
+                   //Added by Jeff Huang\r
+                   //TODO: FIXIT\r
+               } catch (Exception ex) {\r
+                   error(request, "invalid resource class "+cls);\r
+               }\r
+               // Add it to the container:\r
+               try {\r
+                   ((ContainerInterface) r).registerResource(id, child, null);\r
+               } catch (InvalidResourceException ex) {\r
+                   error(request, ex.getMessage());\r
+               }\r
+               // Write back the new resource:\r
+               ByteArrayOutputStream bout = new ByteArrayOutputStream();\r
+               writer.writeResource(child, bout);\r
+               return okReply(request, bout.toByteArray());\r
+           } catch (IOException ex) {\r
+               error(request, "bad request");\r
+           } catch (AdminProtocolException apex) {\r
+               error(request, apex.getMessage());\r
+           }\r
+       } catch (InvalidResourceException ex) {\r
+           error(request, "Invalid resource");\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // not reached:\r
+       return null;\r
+    }\r
+\r
+    public Reply remoteReindexResource(Request request, boolean rec) \r
+       throws ProtocolException\r
+    {\r
+       // Check target resource class:\r
+       ResourceReference rr = lookup(request);\r
+       // Handle request:\r
+       try {\r
+           Resource r = rr.lock();\r
+           if(r != null) {\r
+               if (r instanceof org.w3c.tools.resources.DirectoryResource) {\r
+                   org.w3c.tools.resources.DirectoryResource dir = \r
+                       (org.w3c.tools.resources.DirectoryResource) r;\r
+                   dir.reindex(rec);\r
+                   return okReply(request);\r
+               } else {\r
+                   error(request, "Can't reindex this resource"+\r
+                         "(not a DirectoryResource)");\r
+               }\r
+           } else {\r
+               error(request, "Bad request");\r
+           }\r
+       } catch (InvalidResourceException ex) {\r
+           error(request, "Invalid resource");\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // not reached\r
+       return null;\r
+    }\r
+\r
+    public Reply remoteDeleteResource(Request request) \r
+       throws ProtocolException\r
+    {\r
+       // Check target resource class:\r
+       ResourceReference rr = lookup(request);\r
+       // Handle request:\r
+       try {\r
+           Resource r = rr.lock();\r
+           if(r != null) {\r
+               try {\r
+                   r.delete();\r
+               } catch (MultipleLockException ex) {\r
+                   error(request, ex.getMessage());\r
+               }\r
+               return okReply(request);\r
+           } else {\r
+               error(request, "Bad request");\r
+           }\r
+       } catch (InvalidResourceException ex) {\r
+           error(request, "Invalid resource");\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       // not reached\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * Perform an extended request\r
+     * @param request the incomming request.\r
+     * @exception ProtocolException if a protocol error occurs \r
+     * @exception ResourceException if a server error occurs\r
+     */\r
+    public Reply extended(Request request) \r
+       throws ProtocolException, ResourceException\r
+    {\r
+       String mth = request.getMethod();\r
+       if ( mth.equals("SET-VALUES") ) {\r
+           checkContentType(request);\r
+           return remoteSetValues(request);\r
+       } else if (mth.equals("LOAD-RESOURCE")) {\r
+           return remoteLoadResource(request);\r
+       } else if (mth.equals("REGISTER-RESOURCE") ) {\r
+           checkContentType(request);\r
+           return remoteRegisterResource(request);\r
+       } else if (mth.equals("DELETE-RESOURCE") ) {\r
+           return remoteDeleteResource(request);\r
+       } else if (mth.equals("REINDEX-RESOURCE") ) {\r
+           return remoteReindexResource(request, true);\r
+       } else if (mth.equals("REINDEX-LOCALLY") ) {\r
+           return remoteReindexResource(request, false);\r
+       } else if (mth.equals("UNREGISTER-FRAME")) {\r
+           checkContentType(request);\r
+           return remoteUnregisterFrame(request);\r
+       } else if (mth.equals("REGISTER-FRAME")) {\r
+           checkContentType(request);\r
+           return remoteRegisterFrame(request);\r
+       } else {\r
+           return super.extended(request);\r
+       }\r
+    }\r
+\r
+    /**\r
+     * The default GET method for other king of associated resource\r
+     * @param request The request to handle.\r
+     * @exception ProtocolException If processsing the request failed.\r
+     * @exception ResourceException If the resource got a fatal error.\r
+     */\r
+    protected Reply getOtherResource(Request request) \r
+       throws ProtocolException, ResourceException\r
+    {\r
+       // we don't manage this kind of resource\r
+       Reply error = request.makeReply(HTTP.NOT_IMPLEMENTED) ;\r
+       error.setContent("Method GET not implemented.<br><br>"+\r
+                        "The administration server does not use plain "+\r
+                        "HTTP but a variant of it. The only tool available "+\r
+                        "for now is an application called <b>JigAdmin</b>. "+\r
+                        "Please read the documentation.");\r
+       throw new HTTPException (error) ;\r
+    }\r
+\r
+    public BrokerFrame(ServerHandlerManager shm,\r
+                      AdminServer admin,\r
+                      AdminWriter writer)\r
+    {\r
+       super();\r
+       this.shm    = shm;\r
+       this.admin  = admin;\r
+       this.writer = writer;\r
+    }\r
+\r
+}\r