Do these new classes and interfaces for internet based lookup services have understandable name semantics? Is there anything I've missed?

The purpose of ServiceResultStreamUnmarshaller is to retrieve ServiceItem's from the ResultStream returned by the StreamServiceRegistrar (lookup service), this class is added to the chain of ResultStream objects after filtering has been performed in the result stream by ServiceResultStreamFilter.

Remember from our earlier discussions that ResultStream is similar to MatchSet in Javaspaces, StreamServiceRegistrar and ServiceClasspathSubItem are designed to reduce network traffic and client memory consumption during client side filtering of lookup results.

This work is based on our list discussions, notable contributions were made by Gregg Wonderly and Dan Creswell, once we have something we're happy with I'd like to note their contributions in the source documentation if they're happy for me to do so.

Cheers,

Peter.

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.river.api.lookup;

import java.io.IOException;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
import net.jini.core.lookup.ServiceItem;
import org.apache.river.api.util.ResultStream;

/**
* Defines an extension interface to the lookup service, for use on large or * global networks such as the internet or low bandwidth networks. * The interface is not a remote interface; each implementation of the
* lookup service exports proxy objects that implement the
* StreamServiceRegistrar interface local to the client, using an
* implementation-specific protocol to communicate with the actual remote
* server.  All of the proxy methods obey normal RMI remote interface
* semantics except where explicitly noted.  Two proxy objects are equal if
* they are proxies for the same lookup service.  Every method invocation
* (on both StreamServiceRegistrar and ServiceRegistration) is atomic with
* respect to other invocations.
*
* The StreamServiceRegistrar is intended to perform the same function
* as the ServiceRegistrar, but with the ability to return results as a
* stream, so memory consumption is minimised at the client and network
* communication is minimised between the client and lookup service server.
*
*
* @see ServiceRegistrar
* @see PortableServiceRegistrar
* @see ServiceRegistration
* @author Peter Firmstone
* @since 2.2.0
*/
public interface StreamServiceRegistrar extends ServiceRegistrar{

   /**
* Returns a ResultStream that provides access to ServiceClasspathSubItem * instances. The ResultStream terminates with a null value. The result
    * stream may be infinite, or limited by an integer limit value.
    *
* A ServiceClasspathSubItem implementation instance is a ServiceItem that
    * contains only Objects that are resolvable on the local classpath,
    * this is useful for clients to perform filtering before requiring a
    * download of the actual ServiceItem.
    *
    * @param tmpl template to match
    * specified template
    *
    * @param maxBatchSize held locally, larger batch sizes reduce network
* traffic, but may delay processing locally depending on implementation. * @param limit - Zero for infinite, otherwise limits the number of matching
    * results.
    * @return ResultStream containing ServiceItem's
    * @throws java.io.IOException
    * @see ServiceItem
    * @see ServiceClasspathSubItem
    * @see ResultStream
    * @see ServiceResultStreamFilter
    * @see ResultStreamUnmarshaller
    * @since 2.2.0
    */
   ResultStream lookup(ServiceTemplate tmpl, int maxBatchSize, int limit)
           throws IOException;
}



/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.river.api.lookup;

import java.io.IOException;
import java.security.CodeSource;
import org.apache.river.api.lookup.ServiceClasspathSubItem;
import org.apache.river.api.util.ResultStream;
import net.jini.core.lookup.*;

/**
* Add this to the ResultStream filter chain
* {@link StreamServiceRegistrar#lookup(ServiceTemplate, Class[], int)}
* to getServiceItem any ServiceClasspathSubItem's in the stream, prior to
* proxy verification, or applying constraints.
*
* @author Peter Firmstone.
* @see ServiceClasspathSubItem.
* @see StreamServiceRegistrar
*/
public class ServiceResultStreamUnmarshaller implements ResultStream<ServiceItem> {
   private final ResultStream input;
/**
    * Note the methods of ServiceResultStreamUnmarshaller, implement the
    * generic methods of ResultStream<ServiceItem>, but the constructor
    * doesn't to ensure type safety at the client, where runtime binding
    * prevents the compiler from checking the type.
    */
   public ServiceResultStreamUnmarshaller(ResultStream rs){
       input = rs;
   }

   public ServiceItem get() throws IOException {
   if (input == null) return null;
       for(Object item = input.get(); item != null; item = input.get()) {
           if (item instanceof ServiceClasspathSubItem){
ServiceClasspathSubItem msi = (ServiceClasspathSubItem) item;
               return msi.getServiceItem();
           } else if (item instanceof ServiceItem) {
       return (ServiceItem) item;
       }
/* If item is not an instanceof ServiceItem or ServiceClasspathSubItem
        * it is ignored and the next item in the ResultStream is retrieved.
        */
       }//end item loop
       return null; // Our stream terminated item was null;
   }

   public void close() throws IOException {
   if (input == null) return;
       input.close();
   }

}





/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.river.api.lookup;

import java.io.IOException;
import org.apache.river.api.util.ResultStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.jini.core.lookup.ServiceItem;
import net.jini.lookup.ServiceItemFilter;

/**
* A Filter utility class designed to filter out unwanted results. Filters can * be daisy chained with pre prepared filters to perform logical AND operations.
*
* Logical OR operations can be simulated by providing multiple filters in
* constructors.
*
* Any references to ServiceResultStreamFilter should be set to null
* immediately after filtering.
* New instances can be created as required.
*
* @author Peter Firmstone.
*/
public class ServiceResultStreamFilter implements ResultStream<ServiceItem> {
   private final List<ServiceItemFilter> filters;
   private final ResultStream inputResultStream;
/**
    * Note the methods of ServiceResultStreamFilter implement
    * ResultStream<ServiceItem>, but the constructor doesn't, this is to
    * protect the client against unchecked type casts that would occur
    * if a ResultStream<ServiceItem> was obtained from a service.
    *
    * All methods in this implementation perform their own type safety
    * checks in order to implement ResultStream<ServiceItem> safely.
    *
    * @param rs
    * @param sf
    */
   public ServiceResultStreamFilter(ResultStream rs,
           ServiceItemFilter[] sf){
       inputResultStream = rs;
       filters = new ArrayList<ServiceItemFilter>(sf.length);
       filters.addAll(Arrays.asList(sf));
   }

   public ServiceItem get() throws IOException {
       for(Object item = inputResultStream.get(); item != null;
               item = inputResultStream.get()) {
       if (item instanceof ServiceItem){
       ServiceItem it = (ServiceItem) item;
       int l = filters.size();
       for ( int i = 0; i < l; i++){
           ServiceItemFilter filter = filters.get(i);
           if (filter == null) continue;
           if (filter.check(it))  return it;
       }// end filter loop
       }// If it isn't a ServiceItem it is ignored.
       }//end item loop
       return null; // Our stream terminated item was null;
   }

   public void close() throws IOException {
       inputResultStream.close();
   }
}


/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.river.api.util;

import java.io.IOException;

/**
* This interface is similar to an Enumerator, it is designed to return
* results incrementally in loops, however unlike an Enumerator, there is no
* check first operation as implementors must return a null value after
* the backing data source has been exhausted. So this terminates like a stream
* by returning a null value.
*
* @author Peter Firmstone
*/
public interface ResultStream<T> {
   /**
    * Get next T, call from a loop until T is null;
    * @return T unless end of stream in which case null is returned.
    */
   public T get() throws IOException;
   /**
    * Close the result stream, this allows the implementer to close any
    * resources prior to deleting reference.
    */
   public void close() throws IOException;
}


/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.river.api.lookup;

import java.net.URI;
import java.security.CodeSource;
import net.jini.core.entry.Entry;
import net.jini.core.lookup.ServiceID;
import net.jini.core.lookup.ServiceItem;

/**
* ServiceClasspathSubItem is intended for client side filtering of lookup
* service results prior to clients using a service, the lookup service
* that implements this class, implements #getServiceItem(), so clients
* can obtain a complete ServiceItem when required after filtering.
*
* ServiceClasspathSubItem extends ServiceItem and can be used anywhere a
* ServiceItem is required for querying or inspecting Entry fields that are
* resolvable from the local classpath.  If dynamically downloaded code is
* required, Remote or Serializable object references are not resolved,
* instead, such fields are set to null to avoid codebase download.
*
* ServiceClasspathSubItem inherits all fields from ServiceItem.
*
* Some fields in ServiceClasspathSubItem may be null or fields in Entry's may
* be null or even the service reference may be null, these fields would be
* non-null in a ServiceItem that resolves classes from dynamicly downloaded
* code or a remote codebase.
*
* The serviceID field shall be non-null always.
*
* ServiceItem's toString() method will return a different result for
* ServiceClasspathSubItem instances.
*
* When required, a new ServiceItem that is unmarshalled
* using remote codebases and dynamicly downloaded code can be obtained
* by calling #getServiceItem().
*
* @author Peter Firmstone.
*/
public abstract class ServiceClasspathSubItem extends ServiceItem{
   private static final long SerialVersionUID = 1L;
protected ServiceClasspathSubItem(ServiceID id, Entry[] unmarshalledEntries){
       super(id, (Object) null, unmarshalledEntries);
   }
/* Default constructor for serializable sub class.
    */
   protected ServiceClasspathSubItem(){
       super(null, null, null);
   }
   /**
    * Using remote and local code as required getServiceItem returns a
    * new ServiceItem.
    *
    * The returned ServiceItem must not be an instance of this class.
    *
* @return ServiceItem, totally unmarshalled, using remote codebase resources
    * in addition to any local classpath or resources.
    */
   public abstract ServiceItem getServiceItem();
}

Reply via email to