You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2012/01/21 08:28:36 UTC

svn commit: r1234278 [16/29] - in /river/tck: ./ configs/ doc/ doc/api/ doc/api/com/ doc/api/com/sun/ doc/api/com/sun/jini/ doc/api/com/sun/jini/compat/ doc/api/com/sun/jini/compat/admin1/ doc/api/com/sun/jini/compat/admin2/ doc/api/com/sun/jini/compat...

Added: river/tck/src/com/sun/jini/compat/reggie/ClassResolver.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/ClassResolver.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/ClassResolver.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/ClassResolver.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,226 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.lang.ref.WeakReference;
+import java.lang.ref.ReferenceQueue;
+
+/**
+ * Maps EntryClass and ServiceType instances to canonical instances, so
+ * that equals and isAssignableFrom methods work correctly.  Two instances
+ * are considered equivalent if they have the same class name.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class ClassResolver {
+
+    /** True if recovering log, false otherwise */
+    private boolean inRecovery = false;
+    /** Map from String (classname) to WeakRep(ServiceType) */
+    private final Map serviceMap = new HashMap();
+    /** Reference queue for WeakReps of serviceMap */
+    private final ReferenceQueue serviceRefQueue = new ReferenceQueue();
+    /** Map from String (classname) to WeakRep(EntryClass) */
+    private final Map entryMap = new HashMap();
+    /** Reference queue for WeakReps of entryMap */
+    private final ReferenceQueue entryRefQueue = new ReferenceQueue();
+
+    /** Simple constructor */
+    public ClassResolver() {}
+
+    /** Set whether or not we are recovering log */
+    public void setInRecovery(boolean inRecovery) {
+	this.inRecovery = inRecovery;
+    }
+
+    /** Returns canonical instance of a ServiceType. */
+    public ServiceType resolve(ServiceType stype) {
+	if (stype == null)
+	    return null;
+	synchronized (serviceMap) {
+	    /* remove any queued refs */
+	    while (true) {
+		WeakRep ref = (WeakRep)serviceRefQueue.poll();
+		if (ref == null)
+		    break;
+		serviceMap.remove(ref.name);
+	    }
+	    WeakRep ref = (WeakRep)serviceMap.get(stype.getName());
+	    if (ref != null) {
+		ServiceType rstype = (ServiceType)ref.get();
+		// XXX should worry about type evolution
+		if (rstype != null)
+		    return rstype;
+	    }
+	    resolve(stype.getInterfaces());
+	    stype.canonical(resolve(stype.getSuperclass()));
+	    serviceMap.put(stype.getName(), new WeakRep(stype.getName(),
+							stype,
+							serviceRefQueue));
+	    return stype;
+	}
+    }
+
+    /**
+     * Replaces the elements of the ServiceType array with their
+     * canonical instances.
+     */
+    public void resolve(ServiceType[] stypes) {
+	if (stypes != null) {
+	    for (int i = stypes.length; --i >= 0; ) {
+		stypes[i] = resolve(stypes[i]);
+	    }
+	}
+    }
+
+    /** Returns canonical instance of an EntryClass. */
+    public EntryClass resolve(EntryClass eclass) {
+	if (eclass == null)
+	    return null;
+	synchronized (entryMap) {
+	    /* remove any queued refs */
+	    while (true) {
+		WeakRep ref = (WeakRep)entryRefQueue.poll();
+		if (ref == null)
+		    break;
+		entryMap.remove(ref.name);
+	    }
+	    WeakRep ref = (WeakRep)entryMap.get(eclass.getName());
+	    if (ref != null) {
+		EntryClass reclass = (EntryClass)ref.get();
+		if (reclass != null) {
+		    if (reclass.getNumFields() == eclass.getNumFields() &&
+			(reclass.getFieldsHash() == eclass.getFieldsHash() ||
+			 reclass.getFieldsHash() == 0 ||
+			 eclass.getFieldsHash() == 0))
+		    {
+			if (reclass.getFieldsHash() == 0)
+			    reclass.setFieldsHash(eclass.getFieldsHash());
+			return reclass;
+		    } else if (anyInUse(reclass)) {
+			throw new IncompatibleClassChangeError(
+					eclass.getName() +
+					": different public fields");
+		    }
+		}
+	    }
+	    eclass.canonical(resolve(eclass.getSuperclass()));
+	    entryMap.put(eclass.getName(), new WeakRep(eclass.getName(),
+						       eclass,
+						       entryRefQueue));
+	    return eclass;
+	}
+    }
+
+    /**
+     * Returns true if the log is not being recovered and there are any
+     * instances or templates of the given entry class or any instances or
+     * templates of its known subclasses. If the log is being recovered,
+     * or there are no instances or templates, purge the entry class and
+     * any subclasses.
+     */
+    private boolean anyInUse(EntryClass eclass) {
+	if (!inRecovery && (eclass.getNumInstances() > 0 ||
+			    eclass.getNumTemplates() > 0))
+	    return true;
+	List purges = null;
+	for (Iterator iter = entryMap.values().iterator(); iter.hasNext(); ) {
+	    WeakRep ref = (WeakRep) iter.next();
+	    if (ref != null) {
+		EntryClass reclass = (EntryClass)ref.get();
+		if (reclass != null && eclass.isAssignableFrom(reclass)) {
+		    if (!inRecovery && (reclass.getNumInstances() > 0 ||
+					reclass.getNumTemplates() > 0))
+			return true;
+		    if (purges == null)
+			purges = new ArrayList(1);
+		    purges.add(reclass.getName());
+		}
+	    }
+	}
+	if (purges != null)
+	    entryMap.keySet().removeAll(purges);
+	return false;
+    }
+
+    /**
+     * Replace all embedded descriptors in an Item with their
+     * canonical instances.
+     */
+    public void resolve(Item item) {
+	item.serviceType = resolve(item.serviceType);
+	resolve(item.attributeSets);
+    }
+
+    /**
+     * Replace all embedded descriptors in a Template with their
+     * canonical instances.
+     */
+    public void resolve(Template tmpl) {
+	resolve(tmpl.serviceTypes);
+	resolve(tmpl.attributeSetTemplates);
+    }
+
+    /**
+     * Replace all embedded descriptors in an EntryRep array with their
+     * canonical instances.
+     */
+    public void resolve(EntryRep[] attrSets) {
+	if (attrSets != null) {
+	    for (int i = attrSets.length; --i >= 0; ) {
+		attrSets[i].eclass = resolve(attrSets[i].eclass);
+	    }
+	}
+    }
+
+    /**
+     * Replace all embedded descriptors in an EntryRep array with their
+     * canonical instances, allowing null EntryReps.
+     */
+    public void resolveWithNulls(EntryRep[] attrSets) {
+	if (attrSets != null) {
+	    for (int i = attrSets.length; --i >= 0; ) {
+		if (attrSets[i] != null)
+		    attrSets[i].eclass = resolve(attrSets[i].eclass);
+	    }
+	}
+    }
+
+    /**
+     * A weak ref extended with the key for the map.
+     */
+    private static class WeakRep extends WeakReference {
+	/** The key for the map */
+	public String name;
+
+	/** Always create a queued ref. */
+	public WeakRep(String name, Object referent, ReferenceQueue refQueue)
+	{
+	    super(referent, refQueue);
+	    this.name = name;
+	}
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/ClassResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/CreateLookup.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/CreateLookup.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/CreateLookup.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/CreateLookup.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,113 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import com.sun.jini.start.ServiceStarter;
+
+import net.jini.core.lookup.ServiceRegistrar;
+
+import java.io.IOException;
+import java.rmi.activation.ActivationException;
+import java.rmi.Remote;
+
+import java.util.Properties;
+
+/**
+ * This class contains the public methods and command line interface for
+ * creating an activatable instance of the reggie implementation of the
+ * lookup service. This class employs the utility class 
+ * <code>com.sun.jini.start.ServiceStarter</code> to start the desired
+ * service. That utility class requires that this class define a
+ * <code>public static create</code> method which performs all functions
+ * that are specific to the desired service, and which can be invoked by the
+ * the utility class.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ * @see com.sun.jini.start.ServiceStarter
+ */
+public class CreateLookup {
+    /** The fully-qualified path.classname of this class, which will be
+     *  passed to the <code>com.sun.jini.start.ServiceStarter</code>
+     *  utility class
+     */
+    private static String starterClass = CreateLookup.class.getName();
+    /** The fully-qualified path.classname of the class that defines the
+     *  implementation of the backend server of the service that is to be
+     *  started
+     */
+    private static String implClass = RegistrarImpl.class.getName();
+    /** The name used to identify the particular resource bundle from which
+     *  usage/error message information may be retrieved for display
+     *  (helpful with internationalization)
+     */
+    private static String resourcename = "lookup";
+    /**
+     * Command line interface for starting an instance of the service
+     * referenced in the <code>implClass</code> field
+     * <p>
+     *
+     * @param args <code>String</code> array containing the command line
+     *             arguments
+     *
+     * @see com.sun.jini.start.ServiceStarter
+     */
+    public static void main(String[] args) {
+        ServiceStarter.create(args, starterClass, implClass, resourcename);
+    }//end main
+
+    /**
+     * This method defines how the service referenced in the
+     * <code>implClass</code> field of this class is to be started.
+     * This method will be invoked through reflection by the utility
+     * class <code>com.sun.jini.start.ServiceStarter</code>. This method
+     * performs all functions that require knowledge of, or access to,
+     * the service-specific information; information that the utility
+     * class cannot easily obtain or exploit while attempting to start
+     * the desired service.
+     * <p>
+     * This method returns a proxy that provides client-side access to
+     * the backend server of the started service.
+     *
+     * @param serverStub a <code>Remote</code> reference to the backend server
+     *                   of the started service
+     * 
+     * @return an instance of the public interface to the desired service
+     *         referenced in the <code>implClass</code> field of this class;
+     *         that is, a proxy that provides client-side access to the
+     *         backend server of the started service
+     * 
+     * @throws java.rmi.activation.ActivationException this is a general
+     *         exception thrown by the activation system to indicate a
+     *         a number of exceptional conditions that prevent the
+     *         activation system from fulfilling a particular request.
+     * 
+     * @throws java.io.IOException 
+     *
+     * @see com.sun.jini.start.ServiceStarter
+     */
+    public static ServiceRegistrar create(Remote serverStub)
+                                      throws ActivationException, IOException
+    {
+	return new RegistrarProxy((Registrar)serverStub,
+                                  ((Registrar)serverStub).getServiceID());
+    }//end create
+
+}//end class CreateLookup

Propchange: river/tck/src/com/sun/jini/compat/reggie/CreateLookup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/EntryClass.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/EntryClass.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/EntryClass.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/EntryClass.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,219 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.rmi.server.RMIClassLoader;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+
+/**
+ * An EntryClass is a descriptor for an entry class, packaged up for
+ * transmission between client-side proxies and the registrar server.
+ * Instances are never visible to clients, they are private to the
+ * communication between the proxies and the server.  Note that we don't
+ * transmit information about interfaces implemented by the class, because it
+ * isn't necessary given the specific use of type information for entries.
+ * <p>
+ * This class only has a bare minimum of methods, to minimize
+ * the amount of code downloaded into clients.
+ * <p>
+ * Equality is based on object identity, on the assumption that
+ * ClassResolver is always used and that equality is only interesting
+ * in the registrar.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ * @see ClassMapper
+ * @see ClassResolver
+ */
+class EntryClass implements java.io.Serializable {
+
+    /**
+     * Class name
+     *
+     * @serial
+     */
+    protected String name;
+    /**
+     * Descriptor for the superclass
+     *
+     * @serial
+     */
+    protected EntryClass superclass;
+    /**
+     * Number of public fields
+     *
+     * @serial
+     */
+    protected int numFields;
+    /**
+     * Hash of the public fields
+     *
+     * @serial
+     */
+    protected long hash;
+
+    /** Number of instances of this class in service registrations */
+    protected transient int numInstances;
+    /** Number of templates of this class in event registrations */
+    protected transient int numTemplates;
+    /**
+     * An instance containing only name, no superclass info.
+     * This is only used on the registrar side, to minimize the amount
+     * of info transmitted back to clients.
+     */
+    protected transient EntryClass replacement;
+
+    private static final long serialVersionUID = 529192974214549379L;
+
+    /**
+     * Should only be called by ClassMapper. A SHA-1 message digest is
+     * computed on a stream constructed with: the hash of the superclass
+     * written as a long (if there is a superclass), then for each of the
+     * fields declared by this class (that is, excluding fields from
+     * superclasses) in alphabetic order, the field name written as UTF
+     * followed by the field type name written as UTF. The first 8 bytes of
+     * the digest are used to form a 64-bit hash value.
+     */
+    public EntryClass(Class clazz, EntryClass superclass) {
+	name = clazz.getName();
+	this.superclass = superclass;
+	ClassMapper.EntryField[] fields = ClassMapper.getFields(clazz);
+	numFields = fields.length;
+	if (superclass != null && numFields == superclass.numFields) {
+	    hash = superclass.hash;
+	} else if (numFields != 0) {
+	    try {
+		MessageDigest md = MessageDigest.getInstance("SHA");
+		DataOutputStream out =
+		    new DataOutputStream(
+			new DigestOutputStream(new ByteArrayOutputStream(127),
+					       md));
+		if (superclass != null)
+		    out.writeLong(superclass.hash);
+		for (int i = superclass.numFields; i < fields.length; i++) {
+		    out.writeUTF(fields[i].field.getName());
+		    out.writeUTF(fields[i].field.getType().getName());
+		}
+		out.flush();
+		byte[] digest = md.digest();
+		for (int i = Math.min(8, digest.length); --i >= 0; ) {
+		    hash += ((long) (digest[i] & 0xFF)) << (i * 8);
+		}
+	    } catch (Exception e) {
+		RegistrarProxy.handleException(e);
+		hash = 0;
+	    }
+	}
+    }
+
+    /**
+     * Constructor used for creating replacement instances,
+     * containing only name.
+     */
+    private EntryClass(EntryClass orig) {
+	name = orig.name;
+    }
+
+    /** Return the class name */
+    public String getName() {
+	return name;
+    }
+
+    /** Return the superclass descriptor */
+    public EntryClass getSuperclass() {
+	return superclass;
+    }
+
+    /** Return the number of public fields (including superclasses) */
+    public int getNumFields() {
+	return numFields;
+    }
+
+    /** Return the hash of the public fields */
+    public long getFieldsHash() {
+	return hash;
+    }
+
+    /** Set the hash of the public fields */
+    public void setFieldsHash(long hash) {
+	this.hash = hash;
+    }
+
+    /** Return the number of instances of this class */
+    public int getNumInstances() {
+	return numInstances;
+    }
+
+    /** Set the number of instances of this class */
+    public void setNumInstances(int numInstances) {
+	this.numInstances = numInstances;
+    }
+
+    /** Return the number of templates of this class */
+    public int getNumTemplates() {
+	return numTemplates;
+    }
+
+    /** Set the number of templates of this class */
+    public void setNumTemplates(int numTemplates) {
+	this.numTemplates = numTemplates;
+    }
+
+    /** Return the replacement, if any, containing only name and rep. */
+    public EntryClass getReplacement() {
+	return replacement;
+    }
+
+    /**
+     * This is really only needed in the registrar, but it's very
+     * convenient to have here.
+     * @see Class#isAssignableFrom
+     */
+    public boolean isAssignableFrom(EntryClass cls) {
+	for (EntryClass sup = cls; sup != null; sup = sup.superclass) {
+	    if (this == sup)
+		return true;
+	}
+	return false;
+    }
+
+    /** Converts the descriptor to a Class instance, loading from codebase */
+    public Class toClass(String codebase)
+	throws IOException, ClassNotFoundException
+    {
+	return RMIClassLoader.loadClass(codebase, name);
+    }
+
+    /**
+     * Sets this descriptor to be the canonical one.  Replaces the
+     * superclass with the canonical superclass, and constructs the
+     * replacement object.
+     * <p>
+     * This should only be called by ClassResolver.
+     */
+    public void canonical(EntryClass superclass) {
+	this.superclass = superclass;
+	replacement = new EntryClass(this);
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/EntryClass.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/EntryClassBase.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/EntryClassBase.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/EntryClassBase.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/EntryClassBase.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,78 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import java.rmi.server.RMIClassLoader;
+import java.io.IOException;
+
+/**
+ * An EntryClass annotated with a codebase.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class EntryClassBase implements java.io.Serializable {
+    /**
+     * The EntryClass.
+     *
+     * @serial
+     */
+    public final EntryClass eclass;
+    /**
+     * The codebase.
+     *
+     * @serial
+     */
+    public String codebase;
+
+    private static final long serialVersionUID = 359458147508924971L;
+
+    /** Simple constructor */
+    public EntryClassBase(EntryClass eclass, String codebase) {
+	this.eclass = eclass;
+	this.codebase = codebase;
+    }
+
+    /** Sets the codebase to the codebase of the given class. */
+    public void setCodebase(Class cls) {
+	codebase = RMIClassLoader.getClassAnnotation(cls);
+    }
+
+    /**
+     * Converts an array of EntryClassBase to an array of Class.  If a
+     * class cannot be loaded, it is left as null.
+     */
+    public static Class[] toClass(EntryClassBase[] eclasses)
+    {
+	Class[] classes = null;
+	if (eclasses != null) {
+	    classes = new Class[eclasses.length];
+	    for (int i = eclasses.length; --i >= 0; ) {
+		try {
+		    EntryClassBase eclass = eclasses[i];
+		    classes[i] = eclass.eclass.toClass(eclass.codebase);
+		} catch (Throwable e) {
+		    RegistrarProxy.handleException(e);
+		}
+	    }
+	}
+	return classes;
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/EntryClassBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/EntryRep.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/EntryRep.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/EntryRep.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/EntryRep.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,196 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import net.jini.core.entry.Entry;
+import java.lang.reflect.Field;
+import java.rmi.MarshalledObject;
+import java.rmi.RemoteException;
+import java.rmi.MarshalException;
+import java.io.IOException;
+import com.sun.jini.compat.reggie.ClassMapper.EntryField;
+
+/**
+ * An EntryRep contains the fields of an Entry packaged up for
+ * transmission between client-side proxies and the registrar server.
+ * Instances are never visible to clients, they are private to the
+ * communication between the proxies and the server.
+ * <p>
+ * This class only has a bare minimum of methods, to minimize
+ * the amount of code downloaded into clients.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class EntryRep implements java.io.Serializable, Cloneable {
+
+    /**
+     * The Class of the Entry converted to EntryClass.
+     *
+     * @serial
+     */
+    public EntryClass eclass;
+    /**
+     * The codebase of the entry class.
+     *
+     * @serial
+     */
+    public String codebase;
+    /**
+     * The public fields of the Entry, each converted as necessary to
+     * a MarshalledObject (or left as is if of known java.lang immutable
+     * type).  The fields are in super- to subclass order.
+     *
+     * @serial
+     */
+    public Object[] fields;
+
+    private static final long serialVersionUID = 7539800683869455714L;
+
+    /**
+     * Converts an Entry to an EntryRep.  Any exception that results
+     * is bundled up into a MarshalException.
+     */
+    public EntryRep(Entry entry) throws RemoteException {
+	EntryClassBase ecb = ClassMapper.toEntryClassBase(entry.getClass());
+	eclass = ecb.eclass;
+	codebase = ecb.codebase;
+	try {
+	    EntryField[] efields = ClassMapper.getFields(entry.getClass());
+	    fields = new Object[efields.length];
+	    for (int i = efields.length; --i >= 0; ) {
+		EntryField f = efields[i];
+		Object val = f.field.get(entry);
+		if (f.marshal && val != null)
+		    val = new MarshalledObject(val);
+		fields[i] = val;
+	    }
+	} catch (IOException e) {
+	    throw new MarshalException("error marshalling arguments", e);
+	} catch (IllegalAccessException e) {
+	    throw new MarshalException("error marshalling arguments", e);
+	}
+    }
+
+    /**
+     * Convert back to an Entry.  If the Entry cannot be constructed,
+     * null is returned.  If a field cannot be unmarshalled, it is set
+     * to null.
+     */
+    public Entry get() {
+	try {
+	    Class clazz = eclass.toClass(codebase);
+	    EntryField[] efields = ClassMapper.getFields(clazz);
+	    Entry entry = (Entry)clazz.newInstance();
+	    for (int i = efields.length; --i >= 0; ) {
+		try {
+		    Object val = fields[i];
+		    EntryField f = efields[i];
+		    if (f.marshal && val != null)
+			val = ((MarshalledObject)val).get();
+		    f.field.set(entry, val);
+		} catch (Throwable e) {
+		    RegistrarProxy.handleException(e);
+		}
+	    }
+	    return entry;
+	} catch (Throwable e) {
+	    RegistrarProxy.handleException(e);
+	}
+	return null;
+    }
+
+    /**
+     * We don't need this in the client or the server, but since we
+     * redefine equals we provide a minimal hashCode that works.
+     */
+    public int hashCode() {
+	return eclass.hashCode();
+    }
+
+    /**
+     * EntryReps are equal if they have the same class and the fields
+     * are pairwise equal.  This is really only needed in the server,
+     * but it's very convenient to have here.
+     */
+    public boolean equals(Object obj) {
+	if (obj instanceof EntryRep) {
+	    EntryRep entry = (EntryRep)obj;
+	    if (!eclass.equals(entry.eclass) ||
+		fields.length != entry.fields.length)
+		return false;
+	    for (int i = fields.length; --i >= 0; ) {
+		if ((fields[i] == null && entry.fields[i] != null) ||
+		    (fields[i] != null && !fields[i].equals(entry.fields[i])))
+		    return false;
+	    }	    
+	    return true;
+	}
+	return false;
+    }
+
+    /**
+     * Deep clone (which just means cloning the fields array too).
+     * This is really only needed in the server, but it's very
+     * convenient to have here.
+     */
+    public Object clone() {
+	try { 
+	    EntryRep entry = (EntryRep)super.clone();
+	    entry.fields = (Object[])entry.fields.clone();
+	    return entry;
+	} catch (CloneNotSupportedException e) { 
+	    throw new InternalError();
+	}
+    }
+
+    /**
+     * Converts an array of Entry to an array of EntryRep.  If needCodebase
+     * is false, then the codebase of every EntryRep will be null.
+     */
+    public static EntryRep[] toEntryRep(Entry[] entries, boolean needCodebase)
+	throws RemoteException
+    {
+	EntryRep[] reps = null;
+	if (entries != null) {
+	    reps = new EntryRep[entries.length];
+	    for (int i = entries.length; --i >= 0; ) {
+		if (entries[i] != null) {
+		    reps[i] = new EntryRep(entries[i]);
+		    if (!needCodebase)
+			reps[i].codebase = null;
+		}
+	    }
+	}
+	return reps;
+    }
+
+    /** Converts an array of EntryRep to an array of Entry. */
+    public static Entry[] toEntry(EntryRep[] reps) {
+	Entry[] entries = null;
+	if (reps != null) {
+	    entries = new Entry[reps.length];
+	    for (int i = reps.length; --i >= 0; ) {
+		entries[i] = reps[i].get();
+	    }
+	}
+	return entries;
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/EntryRep.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/EventLease.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/EventLease.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/EventLease.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/EventLease.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,116 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import net.jini.core.lease.*;
+import java.rmi.RemoteException;
+
+/**
+ * When a registrar (lookup service) grants a lease on an event registration
+ * on behalf of some object (client), a proxy is employed to allow the client
+ * to interact with the lease; this class is the implementation of that proxy.
+ * Clients only see instances of this class via the Lease interface.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class EventLease extends RegistrarLease {
+
+    private static final long serialVersionUID = 1322660638288375494L;
+
+    /**
+     * The eventID returned in the EventRegistration.
+     *
+     * @serial
+     */
+    private final long eventID;
+
+    /**
+     * Constructs a lease, granted by a given registrar with a given
+     * expiration time, for an event registration on behalf of a client.
+     *
+     * @param server object representing the registrar that grants the lease
+     * @param eventID ID of the event registration upon which the lease is
+     *        granted
+     * @param leaseID ID of the lease, granted by the registrar, on the event
+     *        registration
+     * @param expiration the time of expiration of the lease being granted
+     */
+    EventLease(Registrar server, long eventID, long leaseID, long expiration) {
+	super(server, leaseID, expiration);
+	this.eventID = eventID;
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void cancel() throws UnknownLeaseException, RemoteException {
+	server.cancelEventLease(eventID, leaseID);
+    }
+
+    /** 
+     * Renews the event lease associated with an instance of this class.
+     * Each instance of this class corresponds to a lease on an event
+     * registration for a particular client. This method renews that 
+     * lease on behalf of the client.
+     *
+     * @param duration the requested duration for the lease being renewed
+     * @return long value representing the new duration that was granted
+     *         for the renewed lease. Note that the duration returned may
+     *         be less than the duration requested.
+     * @exception UnknownLeaseException indicates the lease does not exist;
+     *            typically because the lease has expired.
+     */
+    protected long doRenew(long duration)
+	throws UnknownLeaseException, RemoteException
+    {
+	return server.renewEventLease(eventID, leaseID, duration);
+    }
+
+    // This method's javadoc is inherited from a super class of this class
+    Object getRegID() {
+	return new Long(eventID);
+    }
+
+    /** 
+     * Returns a hash code based on content.
+     *
+     * @return int value representing the hash code for an instance of this
+     *         class.
+     */
+    public int hashCode() {
+	return server.hashCode() ^ (int)eventID ^ (int)leaseID;
+    }
+
+    /** 
+     * Two EventLease objects are defined to be equal if they satisfy
+     * the following conditions:
+     * <ul>
+     *   <li> both objects were generated by the same registrar
+     *   <li> the IDs of the leases associated with each object are equal (==)
+     *   <li> each object's event registration IDs are equal (==)
+     * </ul>
+     */
+    public boolean equals(Object obj) {
+	if (!(obj instanceof EventLease))
+	    return false;
+	EventLease ls = (EventLease)obj;
+	return (server.equals(ls.server) &&
+		eventID == ls.eventID && leaseID == ls.leaseID);
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/EventLease.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/Item.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/Item.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/Item.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/Item.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,153 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import net.jini.core.lookup.*;
+import java.rmi.MarshalledObject;
+import java.rmi.MarshalException;
+import java.rmi.RemoteException;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.server.RemoteObject;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * An Item contains the fields of a ServiceItem packaged up for
+ * transmission between client-side proxies and the registrar server.
+ * Instances are never visible to clients, they are private to the
+ * communication between the proxies and the server.
+ * <p>
+ * This class only has a bare minimum of methods, to minimize
+ * the amount of code downloaded into clients.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class Item implements java.io.Serializable, Cloneable {
+
+    private static final long serialVersionUID = -1287024425418765730L;
+
+    /**
+     * ServiceItem.serviceID.
+     *
+     * @serial
+     */
+    public ServiceID serviceID;
+    /**
+     * The Class of ServiceItem.service converted to ServiceType.
+     *
+     * @serial
+     */
+    public ServiceType serviceType;
+    /**
+     * The codebase of the service object.
+     *
+     * @serial
+     */
+    public String codebase;
+    /**
+     * ServiceItem.service as a MarshalledObject.
+     *
+     * @serial
+     */
+    public MarshalledObject service;
+    /**
+     * ServiceItem.attributeSets converted to EntryReps.
+     *
+     * @serial
+     */
+    public EntryRep[] attributeSets;
+
+    /**
+     * Converts a ServiceItem to an Item.  Any exception that results
+     * is bundled up into a MarshalException.
+     */
+    public Item(ServiceItem item) throws RemoteException {
+	Object svc = item.service;
+	if (svc instanceof Remote) {
+	    try {
+		svc = RemoteObject.toStub((Remote)svc);
+	    } catch (NoSuchObjectException e) {
+	    }
+	}
+	serviceID = item.serviceID;
+	ServiceTypeBase stb = ClassMapper.toServiceTypeBase(svc.getClass());
+	serviceType = stb.type;
+	codebase = stb.codebase;
+	try {
+	    service = new MarshalledObject(svc);
+	} catch (IOException e) {
+	    throw new MarshalException("error marshalling arguments", e);
+	}
+	attributeSets = EntryRep.toEntryRep(item.attributeSets, true);
+    }
+
+    /**
+     * Convert back to a ServiceItem.  If the service object cannot be
+     * constructed, it is set to null.  If an Entry cannot be constructed,
+     * it is set to null.  If a field of an Entry cannot be unmarshalled,
+     * it is set to null.
+     */
+    public ServiceItem get() {
+	Object obj = null;
+	try {
+	    obj = service.get();
+	} catch (Throwable e) {
+	    RegistrarProxy.handleException(e);
+	}
+	return new ServiceItem(serviceID,
+			       obj,
+			       EntryRep.toEntry(attributeSets));
+    }
+
+    /**
+     * Deep clone.  This is really only needed in the server,
+     * but it's very convenient to have here.
+     */
+    public Object clone() {
+	try { 
+	    Item item = (Item)super.clone();
+	    EntryRep[] attrSets = (EntryRep[])item.attributeSets.clone();
+	    for (int i = attrSets.length; --i >= 0; ) {
+		attrSets[i] = (EntryRep)attrSets[i].clone();
+	    }
+	    item.attributeSets = attrSets;
+	    return item;
+	} catch (CloneNotSupportedException e) { 
+	    throw new InternalError();
+	}
+    }
+
+    /**
+     * Converts an ArrayList of Item to an array of ServiceItem.
+     */
+    public static ServiceItem[] toServiceItem(ArrayList reps)
+    {
+	ServiceItem[] items = null;
+	if (reps != null) {
+	    items = new ServiceItem[reps.size()];
+	    for (int i = items.length; --i >= 0; ) {
+		items[i] = ((Item)reps.get(i)).get();
+	    }
+	}
+	return items;
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/Item.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/Matches.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/Matches.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/Matches.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/Matches.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,65 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import net.jini.core.lookup.*;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+
+/**
+ * A Matches contains the fields of a ServiceMatches packaged up for
+ * transmission between client-side proxies and the registrar server.
+ * Instances are never visible to clients, they are private to the
+ * communication between the proxies and the server.
+ * <p>
+ * This class only has a bare minimum of methods, to minimize
+ * the amount of code downloaded into clients.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class Matches implements java.io.Serializable {
+
+    /**
+     * ServiceMatches.items as an ArrayList of Item
+     *
+     * @serial
+     */
+    public ArrayList items;
+    /**
+     * ServiceMatches.totalMatches
+     *
+     * @serial
+     */
+    public int totalMatches;
+
+    private static final long serialVersionUID = 4446148021075494999L;
+
+    /** Simple constructor. */
+    public Matches(ArrayList items, int totalMatches) {
+	this.items = items;
+	this.totalMatches = totalMatches;
+    }
+
+    /** Converts a Matches to a ServiceMatches. */
+    ServiceMatches get() throws RemoteException {
+	return new ServiceMatches(Item.toServiceItem(items), totalMatches);
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/Matches.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/Registrar.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/Registrar.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/Registrar.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/Registrar.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,197 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import java.io.IOException;
+import java.rmi.RemoteException;
+import java.rmi.MarshalledObject;
+import net.jini.core.entry.Entry;
+import net.jini.core.lookup.*;
+import net.jini.core.event.*;
+import net.jini.admin.Administrable;
+import net.jini.core.discovery.LookupLocator;
+import net.jini.core.lease.UnknownLeaseException;
+
+/**
+ * Registrar defines the private protocol between the various client-side
+ * proxies and the registrar server.
+ * <p>
+ * The declared methods are pretty straightforward transformations of the
+ * ServiceRegistrar and ServiceRegistration interfaces, with external classes
+ * (ServiceItem, ServiceTemplate, ServiceMatches, Entry) converted to internal
+ * classes (Item, Template, Matches, EntryRep).  In addition, there are
+ * methods for transformed Lease and LeaseMap interfaces, for service and
+ * event leases.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+interface Registrar extends java.rmi.Remote, Administrable, RegistrarAdmin {
+
+    /**
+     * Register a new service or re-register an existing service.
+     * @see net.jini.core.lookup.ServiceRegistrar#register
+     */
+    ServiceRegistration register(Item item, long leaseDuration)
+	throws RemoteException;
+
+    /**
+     * Returns the service object (i.e., just ServiceItem.service) from an
+     * item matching the template, or null if there is no match.
+     * @see net.jini.core.lookup.ServiceRegistrar#lookup
+     */
+    MarshalledObject lookup(Template tmpl) throws RemoteException;
+
+    /**
+     * Returns at most maxMatches items matching the template, plus the total
+     * number of items that match the template.
+     * @see net.jini.core.lookup.ServiceRegistrar#lookup
+     */
+    Matches lookup(Template tmpl, int maxMatches) throws RemoteException;
+
+    /**
+     * Registers for event notification.
+     * @see net.jini.core.lookup.ServiceRegistrar#notify
+     */
+    EventRegistration notify(Template tmpl,
+			     int transitions,
+			     RemoteEventListener listener,
+			     MarshalledObject handback,
+			     long leaseDuration)
+	throws RemoteException;
+
+    /**
+     * Looks at all service items that match the specified template, finds
+     * every entry (among those service items) that either doesn't match any
+     * entry templates or is a subclass of at least one matching entry
+     * template, and returns the set of the (most specific) classes of those
+     * entries.
+     * @see net.jini.core.lookup.ServiceRegistrar#getEntryClasses
+     */
+    EntryClassBase[] getEntryClasses(Template tmpl) throws RemoteException;
+
+    /**
+     * Looks at all service items that match the specified template, finds
+     * every entry (among those service items) that matches
+     * tmpl.attributeSetTemplates[setIndex], and returns the set of values
+     * of the specified field of those entries.
+     * The field name has been converted to an index (fields numbered
+     * from super to subclass).
+     *
+     * @see net.jini.core.lookup.ServiceRegistrar#getFieldValues
+     */
+    Object[] getFieldValues(Template tmpl, int setIndex, int field)
+	throws RemoteException;
+
+    /**
+     * Looks at all service items that match the specified template, and for
+     * every service item finds the most specific type (class or interface)
+     * or types the service item is an instance of that are neither equal to,
+     * nor a superclass of, any of the service types in the template and that
+     * have names that start with the specified prefix, and returns the set
+     * of all such types.
+     * @see net.jini.core.lookup.ServiceRegistrar#getServiceTypes
+     */
+    ServiceTypeBase[] getServiceTypes(Template tmpl, String prefix)
+	throws RemoteException;
+
+    /**
+     * Returns the service id of the lookup service.
+     * @see net.jini.core.lookup.ServiceRegistrar#getServiceID
+     */
+    ServiceID getServiceID() throws RemoteException;
+
+    /**
+     * Returns a LookupLocator that can be used if necessary for unicast
+     * discovery of the lookup service.
+     * @see net.jini.core.lookup.ServiceRegistrar#getLocator
+     */
+    LookupLocator getLocator() throws RemoteException;
+
+    /**
+     * Adds the specified attribute sets (those that aren't duplicates of
+     * existing attribute sets) to the registered service item.
+     * @see net.jini.core.lookup.ServiceRegistration#addAttributes
+     */
+    void addAttributes(ServiceID serviceID, long leaseID, EntryRep[] attrSets)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Modifies existing attribute sets of a registered service item.
+     * @see net.jini.core.lookup.ServiceRegistration#modifyAttributes
+     */
+    void modifyAttributes(ServiceID serviceID,
+			 long leaseID,
+			 EntryRep[] attrSetTmpls,
+			 EntryRep[] attrSets)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Deletes all of the service item's existing attributes, and replaces
+     * them with the specified attribute sets.
+     * @see net.jini.core.lookup.ServiceRegistration#setAttributes
+     */
+    void setAttributes(ServiceID serviceID, long leaseID, EntryRep[] attrSets)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Cancels a service lease.
+     * @see net.jini.core.lease.Lease#cancel
+     */
+    void cancelServiceLease(ServiceID serviceID, long leaseID)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Renews a service lease.
+     * @see net.jini.core.lease.Lease#renew
+     */
+    long renewServiceLease(ServiceID serviceID, long leaseID, long duration)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Cancels an event lease.
+     * @see net.jini.core.lease.Lease#cancel
+     */
+    void cancelEventLease(long eventID, long leaseID)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Renews an event lease.
+     * @see net.jini.core.lease.Lease#renew
+     */
+    long renewEventLease(long eventID, long leaseID, long duration)
+	throws UnknownLeaseException, RemoteException;
+
+    /**
+     * Renews service and event leases from a LeaseMap.
+     * @see net.jini.core.lease.LeaseMap#renewAll
+     */
+    RenewResults renewLeases(Object[] regIDs,
+			     long[] leaseIDs,
+			     long[] durations)
+	throws RemoteException;
+
+    /**
+     * Cancels service and event leases from a LeaseMap.
+     * @see net.jini.core.lease.LeaseMap#cancelAll
+     */
+    Exception[] cancelLeases(Object[] regIDs, long[] leaseIDs)
+	throws RemoteException;
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/Registrar.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/RegistrarAdmin.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/RegistrarAdmin.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/RegistrarAdmin.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/RegistrarAdmin.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,224 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import java.io.IOException;
+import java.rmi.RemoteException;
+import net.jini.core.entry.Entry;
+import net.jini.lookup.DiscoveryAdmin;
+import net.jini.admin.JoinAdmin;
+import com.sun.jini.admin.StorageLocationAdmin;
+import com.sun.jini.admin.DestroyAdmin;
+
+/**
+ * An administrative interface for the com.sun.jini.compat.reggie implementation
+ * of the lookup service.
+ *
+ * The algorithm for granting leases is adaptive, and is configured
+ * using the following parameters:
+ * <ul>
+ * <li> lower bound on the maximum service lease (minMaxServiceLease)
+ * <li> lower bound on the maximum event lease (minMaxEventLease)
+ * <li> minimum average interval between lease renewals (minRenewalInterval)
+ * </ul>
+ * The idea is that you don't want renewals coming in too frequently (you
+ * don't want them coming faster than the lookup service can process them,
+ * and you want to leave time for other requests), but you still want
+ * renewals to be relatively timely (so that the information in the
+ * lookup service is fresh).  The lower bounds are the ideal, but the
+ * actual will vary if the ideal would keep the lookup service too busy.
+ * <p>
+ * The maximum service lease granted is never less than minMaxServiceLease,
+ * and the maximum event lease granted is never less than minMaxEventLease.
+ * However, longer leases will be granted if, based on the current number of
+ * service and event registrations, the expected average time between lease
+ * renewals would be less than minRenewalInterval.  When longer leases must
+ * be granted to maintain the required renewal interval, the ratio of the
+ * maximum service lease to the maximum event lease is kept constant.  The
+ * computation of the expected average renewal interval makes the simplifying
+ * assumptions that all lease requests are for the maximum amount of time
+ * (for their respective lease type), all leases will be renewed, and the
+ * renewals will be uniformly distributed in time.  At least the first two
+ * should be reasonable assumptions in the steady state.
+ * <p>
+ * Lease requests for Lease.ANYLENGTH are treated the same as Lease.FOREVER.
+ * <p>
+ * The remaining comments here describe the Registrar with respect to
+ * the following set of method pairs:
+ * <ul>
+ *  <li> setLogFileWeight()          and getLogFileWeight()
+ *  <li> setSnapshotWeight()         and getSnapshotWeight()
+ *  <li> setLogToSnapshotThreshold() and getLogToSnapshotThreshold()
+ * </ul>
+ * The intent of the information contained in this note is to 
+ * clarify the use of these methods and the effect that use will have
+ * on a lookup service's configuration.
+ * <p>
+ * While a lookup service is running, services are added and removed
+ * from the lookup service; attributes are added, modified and deleted
+ * from the registered services; service leases and/or event leases
+ * are requested, renewed and expired. In order to make the lookup
+ * service's state persistent across system crashes or network outages,
+ * each of the state changes just described are written to a file
+ * referred to as the "log file". Thus, the log file records, over
+ * time, the incremental changes -- or "deltas" -- made to the lookup
+ * service's state.
+ * <p>
+ * To prevent the log file from growing indefinitely, the lookup
+ * service's complete state is intermittently written to another
+ * file referred to as a "snapshot file". When the current state is
+ * written to the snapshot file, the log file is cleared and the
+ * incremental logging of deltas begins again. The period prior to
+ * the creation of the first snapshot is referred to as the "system
+ * ramp-up"; this is the only period where a log file exists without
+ * a corresponding snapshot file. 
+ * <p>
+ * When recovering the system's state after a crash or network outage
+ * (or after the lookup service or its ActivationGroup has been 
+ * un-registered and then re-registered through the Activation daemon),
+ * a "base state" is first recovered by retrieving and applying the
+ * contents of the snapshot file (if it exists). Then, if the log
+ * file has length greater than zero, its contents are retrieved
+ * and applied in order to incrementally recover the state 
+ * changes that occurred from the point of the base state.
+ * <p>
+ * The criteria used by the lookup service to determine exactly when
+ * to "take a snapshot" depends on the current size of the log file
+ * relative to the size that the snapshot file will be. Note that 
+ * whereas, the size of the log file depends on the total number 
+ * of changes to the lookup service's state, the size of the snapshot 
+ * file depends on the number of services currently registered; that
+ * is, the more services registered, the larger the snapshot.
+ * For example, if only 10 services are registered, the snapshot 
+ * file will be relatively small; but lease renewals may be regularly
+ * requested on some of those services. The regular lease renewals
+ * will result in a very large log file.
+ * <p>
+ * A balance must be maintained between how large the log file is
+ * allowed to get and how often a snapshot is taken; taking snapshots
+ * too often can slow down processing significantly. The lookup 
+ * service is initially configured with a threshold value and a
+ * weighting factor that are employed in a computation that 
+ * determines when to take a snapshot. The methods referenced above
+ * (and declared below) provide ways to retrieve and change these
+ * values. Thus, based on a particular lookup service's makeup,
+ * these methods can be used by a lookup service's administrative
+ * client to "tune" performance with respect to logging persistent
+ * state.
+ * <pre>
+ * The following comparison is made to determine when to take a snapshot:
+ * 
+ *   if ( logSize >= (W*snapshotSize) && (snapshotSize >= T) {
+ *       take a snapshot;
+ *   }
+ *       where W = snapshotWeight
+ *             T = logToSnapshotThreshold
+ * </pre>
+ * The first comparison is used to ensure that the log file does not
+ * grow too large. The second comparison ensures that snapshots are
+ * not taken too often.
+ * <p>
+ * The Administrative client of a lookup service should make note of
+ * these relationships when using the methods below to tune the
+ * persistence mechanism.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+public interface RegistrarAdmin
+    extends DiscoveryAdmin, StorageLocationAdmin, DestroyAdmin, JoinAdmin
+{
+    /**
+     * Change the lower bound for the maximum value allowed by the
+     * lookup service for any service lease, in milliseconds.
+     *
+     * @param leaseDuration lower bound for maximum service lease,
+     * in milliseconds
+     */
+    void setMinMaxServiceLease(long leaseDuration) throws RemoteException;
+
+    /**
+     * Retrieve the lower bound for the maximum value allowed by the
+     * lookup service for any service lease, in milliseconds.
+     */
+    long getMinMaxServiceLease() throws RemoteException;
+
+    /**
+     * Change the lower bound for the maximum value allowed by the
+     * lookup service for any event lease, in milliseconds.
+     *
+     * @param leaseDuration lower bound for maximum event lease,
+     * in milliseconds
+     */
+    void setMinMaxEventLease(long leaseDuration) throws RemoteException;
+
+    /**
+     * Retrieve the lower bound for the maximum value allowed by the
+     * lookup service for any event lease, in milliseconds.
+     */
+    long getMinMaxEventLease() throws RemoteException;
+
+    /**
+     * Change the minimum average interval between lease renewals, in
+     * milliseconds.
+     *
+     * @param interval minimum average interval between lease renewals,
+     * in milliseconds
+     */
+    void setMinRenewalInterval(long interval) throws RemoteException;
+
+    /**
+     * Retrieve the minimum average interval between lease renewals, in
+     * milliseconds.
+     */
+    long getMinRenewalInterval() throws RemoteException;
+
+    /**
+     * Change the weight factor applied by the lookup service to the 
+     * snapshot size during the test to determine whether or not to
+     * take a "snapshot" of the system state.
+     *
+     * @param weight weight factor for snapshot size
+     */
+    void setSnapshotWeight(float weight) throws RemoteException;
+
+    /**
+     * Retrieve the weight factor applied by the lookup service to the 
+     * snapshot size during the test to determine whether or not to
+     * take a "snapshot" of the system state.
+     */
+    float getSnapshotWeight() throws RemoteException;
+
+    /**
+     * Change the value of the size threshold of the snapshot; which is
+     * employed by the lookup service in the test to determine whether
+     * or not to take a "snapshot" of the system state.
+     *
+     * @param threshold size threshold for taking a snapshot
+     */
+    void setLogToSnapshotThreshold(int threshold) throws RemoteException;
+
+    /**
+     * Retrieve the value of the size threshold of the snapshot; which is
+     * employed by the lookup service in the test to determine whether
+     * or not to take a "snapshot" of the system state.
+     */
+    int getLogToSnapshotThreshold() throws RemoteException;
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/RegistrarAdmin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/RegistrarAdminProxy.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/RegistrarAdminProxy.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/RegistrarAdminProxy.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/RegistrarAdminProxy.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,241 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import net.jini.core.lookup.*;
+import net.jini.core.event.*;
+import net.jini.core.lease.UnknownLeaseException;
+import net.jini.core.discovery.LookupLocator;
+import net.jini.core.entry.Entry;
+import java.io.IOException;
+import java.io.Serializable;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.MarshalledObject;
+import java.lang.reflect.Field;
+
+/**
+ * A RegistrarAdminProxy is a proxy for a registrar.  Clients only see
+ * instances via the RegistrarAdmin interface.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class RegistrarAdminProxy implements RegistrarAdmin, Serializable {
+
+    private static final long serialVersionUID = -9209068398322115525L;
+
+    /**
+     * The registrar
+     *
+     * @serial
+     */
+    private final Registrar server;
+    /**
+     * The registrar's service ID
+     *
+     * @serial
+     */
+    private final ServiceID serviceID;
+
+    /** Simple constructor. */
+    public RegistrarAdminProxy(Registrar server, ServiceID serviceID) {
+	this.server = server;
+	this.serviceID = serviceID;
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public Entry[] getLookupAttributes() throws RemoteException {
+	return server.getLookupAttributes();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void addLookupAttributes(Entry[] attrSets) throws RemoteException {
+	server.addLookupAttributes(attrSets);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void modifyLookupAttributes(Entry[] attrSetTemplates,
+				       Entry[] attrSets)
+	throws RemoteException
+    {
+	server.modifyLookupAttributes(attrSetTemplates, attrSets);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public String[] getLookupGroups() throws RemoteException {
+	return server.getLookupGroups();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void addLookupGroups(String[] groups) throws RemoteException {
+	server.addLookupGroups(groups);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void removeLookupGroups(String[] groups) throws RemoteException {
+	server.removeLookupGroups(groups);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setLookupGroups(String[] groups) throws RemoteException {
+	server.setLookupGroups(groups);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public LookupLocator[] getLookupLocators() throws RemoteException {
+	return server.getLookupLocators();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void addLookupLocators(LookupLocator[] locators)
+	throws RemoteException
+    {
+	server.addLookupLocators(locators);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void removeLookupLocators(LookupLocator[] locators)
+	throws RemoteException
+    {
+	server.removeLookupLocators(locators);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setLookupLocators(LookupLocator[] locators)
+	throws RemoteException
+    {
+	server.setLookupLocators(locators);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void addMemberGroups(String[] groups) throws RemoteException {
+        server.addMemberGroups(groups);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void removeMemberGroups(String[] groups) throws RemoteException {
+        server.removeMemberGroups(groups);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public String[] getMemberGroups() throws RemoteException {
+        return server.getMemberGroups();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setMemberGroups(String[] groups) throws RemoteException {
+        server.setMemberGroups(groups);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public int getUnicastPort() throws RemoteException {
+        return server.getUnicastPort();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setUnicastPort(int port) throws IOException, RemoteException
+    {
+        server.setUnicastPort(port);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setMinMaxServiceLease(long leaseDuration)
+	throws RemoteException
+    {
+        server.setMinMaxServiceLease(leaseDuration);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public long getMinMaxServiceLease() throws RemoteException {
+        return server.getMinMaxServiceLease();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setMinMaxEventLease(long leaseDuration) throws RemoteException
+    {
+        server.setMinMaxEventLease(leaseDuration);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public long getMinMaxEventLease() throws RemoteException {
+        return server.getMinMaxEventLease();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setMinRenewalInterval(long interval) throws RemoteException {
+        server.setMinRenewalInterval(interval);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public long getMinRenewalInterval() throws RemoteException {
+        return server.getMinRenewalInterval();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setSnapshotWeight(float weight) throws RemoteException {
+        server.setSnapshotWeight(weight);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public float getSnapshotWeight() throws RemoteException {
+        return server.getSnapshotWeight();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setLogToSnapshotThreshold(int threshold) throws RemoteException
+    {
+        server.setLogToSnapshotThreshold(threshold);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public int getLogToSnapshotThreshold() throws RemoteException {
+        return server.getLogToSnapshotThreshold();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public String getStorageLocation() throws RemoteException {
+        return server.getStorageLocation();
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void setStorageLocation(String location)
+                                   throws IOException, RemoteException {
+        server.setStorageLocation(location);
+    }
+
+    // This method's javadoc is inherited from an interface of this class
+    public void destroy() throws RemoteException {
+	server.destroy();
+    }
+
+    /** Returns the hash code generated by the hashCode method of the
+     *  service ID associated with an instance of this class.
+     */
+    public int hashCode() {
+	return serviceID.hashCode();
+    }
+
+    /** Proxies for servers with the same serviceID are considered equal. */
+    public boolean equals(Object obj) {
+	return (obj instanceof RegistrarAdminProxy &&
+		serviceID.equals(((RegistrarAdminProxy)obj).serviceID));
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/RegistrarAdminProxy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: river/tck/src/com/sun/jini/compat/reggie/RegistrarEvent.java
URL: http://svn.apache.org/viewvc/river/tck/src/com/sun/jini/compat/reggie/RegistrarEvent.java?rev=1234278&view=auto
==============================================================================
--- river/tck/src/com/sun/jini/compat/reggie/RegistrarEvent.java (added)
+++ river/tck/src/com/sun/jini/compat/reggie/RegistrarEvent.java Sat Jan 21 07:28:27 2012
@@ -0,0 +1,82 @@
+
+/*
+ * 
+ * Copyright 2005 Sun Microsystems, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * 	http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package com.sun.jini.compat.reggie;
+
+import net.jini.core.lookup.*;
+
+/**
+ * Concrete implementation class for abstract ServiceEvent.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class RegistrarEvent extends ServiceEvent {
+
+    private static final long serialVersionUID = 682875199093169678L;
+
+    /**
+     * The new state of the item, or null if the item has been
+     * deleted from the lookup service.  This is either a ServiceItem
+     * or an Item (to be converted to a ServiceItem when unmarshalled).
+     *
+     * @serial
+     */
+    protected Object item;
+
+    /**
+     * Simple constructor.
+     *
+     * @param source the ServiceRegistrar that generated the event
+     * @param eventID the registration eventID
+     * @param seqNo the sequence number of this event
+     * @param handback the client handback
+     * @param serviceID the serviceID of the item that triggered the event
+     * @param transition the transition that triggered the event
+     * @param item the new state of the item, or null if deleted
+     */
+    public RegistrarEvent(Object source,
+			  long eventID,
+			  long seqNo,
+			  java.rmi.MarshalledObject handback,
+			  ServiceID serviceID,
+			  int transition,
+			  Item item)
+    {
+	super(source, eventID, seqNo, handback, serviceID, transition);
+	this.item = item;
+    }
+
+    /**
+     * Returns the new state of the item, or null if the item was deleted
+     * from the lookup service.
+     */
+    public ServiceItem getServiceItem() {
+	return (ServiceItem)item;
+    }
+
+    /** If item is an Item, convert it to a ServiceItem. */
+    private void readObject(java.io.ObjectInputStream stream)
+	throws java.io.IOException, ClassNotFoundException
+    {
+	stream.defaultReadObject();
+	if (item instanceof Item)
+	    item = ((Item)item).get();
+    }
+}

Propchange: river/tck/src/com/sun/jini/compat/reggie/RegistrarEvent.java
------------------------------------------------------------------------------
    svn:eol-style = native