// AdminReader.java 
// $Id: AdminReader.java,v 1.6 1997/07/30 12:04:19 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html


package w3c.jigsaw.admin;

import java.io.*;
import java.net.*;
import java.util.*;

import w3c.tools.store.*;
import w3c.jigsaw.resources.*;

class AdminReader implements AdminProtocol {
    /**
     * The RemoteResource factory to create remote resource instances.
     */
    RemoteResourceFactory factory = null;
    /**
     * The client side admin object we are attached to.
     */
    protected AdminContext admin = null;
    
    private RemoteResource readRawResource(URL parent
					  , String identifier
					  , DataInputStream in)
	throws IOException, AdminProtocolException
    {
	// Read the class hierarchy:
	Vector vector  = new Vector();
	int    clssz   = in.readInt();
	while (--clssz >= 0)
	    vector.addElement(in.readUTF());
	// And the identifier:
	String wireid = in.readUTF();
	wireid = (wireid.equals("")) ? null : wireid;
	String classes[] = new String[vector.size()];
	vector.copyInto(classes);
	if (identifier != null) {
	    // if ((wireid != null) && ! identifier.equals(wireid) )
	    // throw new RuntimeException("Implementation bug");
	    ;
	} else {
	    identifier = wireid;
	}
	// Create the RemoteResource with these infos:
	return factory.createRemoteResource(parent, identifier, classes);
    }
    
    private RemoteResource readRawResource(URL url
					   , DataInputStream in)
	throws IOException, AdminProtocolException
    {
	// Read the class hierarchy:
	Vector vector  = new Vector();
	int    clssz   = in.readInt();
	while (--clssz >= 0)
	    vector.addElement(in.readUTF());
	// And the resource identifier:
	String wireid = in.readUTF();
	String classes[] = new String[vector.size()];
	vector.copyInto(classes);
	// Create the RemoteResource with these infos:
	return factory.createRemoteResource(url, classes);
    }
    
    protected RemoteResource readResource(URL parent
					  , String identifier
					  , DataInputStream in)
	throws IOException, AdminProtocolException
    {
	int op = in.read();
	switch(op) {
	  case WIRED_PLAIN:
	      return readRawResource(parent, identifier, in);
	  case WIRED_FILTERED:
	      int            nf        = in.readInt();
	      RemoteResource filters[] = null;
	      if ( nf > 0 ) {
		  filters = new RemoteResource[nf];
		  for (int i = 0 ; i < nf; i++) {
		      String fid = in.readUTF();
		      URL    url = null;
		      try {
			  url = new URL(parent, identifier+"?"+fid);
		      } catch (MalformedURLException ex) {
			  ex.printStackTrace();
		      }
		      filters[i] = readRawResource(url, in);
		      ((PlainRemoteResource) filters[i]).identifier = fid;
		  }
	      } 
	      PlainRemoteResource r = null;
	      r = (PlainRemoteResource) readRawResource(parent,identifier,in);
	      r.setFilters(filters);
	      return r;
	  default:
	      throw new RuntimeException("unknown opcode: "+op);
	}
    }

    protected Attribute[] readAttributes(DataInputStream in)
	throws IOException, AdminProtocolException
    {
	ObjectInputStream oin = new ObjectInputStream(in);
	try {
	    return (Attribute[]) oin.readObject();
	} catch (ClassNotFoundException ex) {
	    ex.printStackTrace();
	} catch (StreamCorruptedException ex) {
	    ex.printStackTrace();
	} catch (OptionalDataException ex) {
	    ex.printStackTrace();
	}
	throw new AdminProtocolException("Cannot restore attributes");
    }
    


    AdminReader(AdminContext admin) {
	this.admin   = admin;
	this.factory = new RemoteResourceFactory(admin);
    }
    
}


