You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by rj...@apache.org on 2009/06/09 14:00:32 UTC

svn commit: r782968 [3/7] - in /directory/sandbox/slp: ./ src/main/java/org/apache/directory/slp/ src/main/java/org/apache/directory/slp/codec/ src/main/java/org/apache/directory/slp/extensions/ src/main/java/org/apache/directory/slp/impl/ src/main/jav...

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,259 @@
+/* 
+ *   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.directory.slp.extensions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.impl.AuthenticationBlock;
+import org.apache.directory.slp.impl.SLPCore;
+import org.apache.directory.slp.impl.SLPUtils;
+import org.apache.mina.core.buffer.IoBuffer;
+
+
+/**
+ * The attribute list extension for SLP as described in rfc 3059
+ * 
+ * @author Lorenz Breu
+ */
+public class AttributeListExtension extends AbstractExtension{
+
+
+	/*The format of the Attribute List Extension is as follows:
+
+	       0                   1                   2                   3
+	       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+	      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	      |      Extension ID = 0x0002    |     Next Extension Offset     |
+	      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	      | Offset, contd.|      Service URL Length       |  Service URL  /
+	      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	      |     Attribute List Length     |         Attribute List        /
+	      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	      |# of AttrAuths |-(if present) Attribute Authentication Blocks.../
+	      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+	   The Extension ID is 0x0002.
+	 */
+
+
+
+
+	private int nextExtensionOffset;
+
+	private String url;
+
+	private String attributeList;
+
+	private AuthenticationBlock[] authBlocks = new AuthenticationBlock[]{};
+
+	public AttributeListExtension(){
+		super(ATTRIBUTE_LIST_EXTENSION);
+	}
+	
+	public AttributeListExtension(String url, String attributes){
+		super(ATTRIBUTE_LIST_EXTENSION);
+		this.url = url;
+		this.attributeList = attributes;
+	}
+
+	public void setNextExtensionOffset(int neo){
+		nextExtensionOffset = neo;
+	}
+
+	public int getNextExtensionOffset(){
+		return nextExtensionOffset;
+	}
+
+	public void setUrl(String serviceUrl){
+		url = serviceUrl;
+	}
+
+
+	public String getUrl(){
+		return url;
+	}
+
+	public void setAttributeList(String attributeList){
+		this.attributeList = attributeList;
+	}
+
+	public String getAttributeList(){
+		return attributeList;
+	}
+
+	public void setAuthenticationBlocks(AuthenticationBlock[] authenticationBlocks){
+		authBlocks = authenticationBlocks;
+	}
+
+	public AuthenticationBlock[] getAuthenticationBlocks() {
+		return authBlocks;
+	}
+
+
+	@Override
+	public int getLength(){
+		int authLength = 0;
+		for (AuthenticationBlock ab : authBlocks){
+			authLength+=ab.getLength();
+		}
+		return (2 + 3 + 2 + url.length() + 2 + attributeList.length() + 1 + authLength);
+	}
+
+
+	protected void decodeBody(final IoBuffer buf, final short id, final int nextOffset) throws Exception{
+		url = decodeString(buf);
+		attributeList = decodeString(buf);
+		authBlocks=decodeAuthBlocks(buf);
+	}
+
+	public void encodeBody(IoBuffer buf){
+		try {
+			encodeString(buf, url);
+			encodeString(buf, attributeList);
+			encodeAuthBlocks(authBlocks, buf);
+		} catch (Exception e){
+			SLPCore.getPlatform().logDebug("[Extensions]: Error encoding an Attribute List Extension: " + e.getMessage());
+		}
+	}
+
+
+	/**
+	 * 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Block
+	 * Structure Descriptor | Authentication Block Length |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+	 * Timestamp |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SLP
+	 * SPI String Length | SLP SPI String \
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+	 * Structured Authentication Block ... \
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * 
+	 * @param session
+	 * @param in
+	 * @return
+	 */
+	protected final AuthenticationBlock[] decodeAuthBlocks(final IoBuffer in) throws Exception {
+		final short blocks = (short) in.get();
+		final AuthenticationBlock[] result = new AuthenticationBlock[blocks];
+		for (int i = 0; i < blocks; i++) {
+			final short bsd = (short) in.getShort();
+			if (bsd != AuthenticationBlock.BSD_DSA) {
+				throw new ServiceLocationException(
+						ServiceLocationException.AUTHENTICATION_FAILED, "BSD "
+						+ bsd + " is not supported.");
+			}
+			final int size = in.getShort();
+			final int timestamp = in.getInt();
+			final String spi = decodeString(in);
+			final byte[] sig = new byte[size - 2 - 2 - 4 - 2
+			                            - spi.getBytes().length];
+			in.get(sig);
+			result[i] = new AuthenticationBlock(timestamp, spi, sig);
+		}
+
+		// return SLPCore.CONFIG.getSecurityEnabled() ? result
+		// : new AuthenticationBlock[0];
+		return result;
+	}
+
+	protected final void encodeAuthBlocks(
+			final AuthenticationBlock[] authBlocks,
+			final IoBuffer out) throws Exception {
+		// FIXME: hack
+		if (authBlocks == null) {
+			out.put((byte) 0);
+			return;
+		}
+		out.put((byte) authBlocks.length);
+		for (int i = 0; i < authBlocks.length; i++) {
+			final int pos = out.position();
+			out.putShort(AuthenticationBlock.BSD_DSA); // BSD
+			out.skip(2); // skip the length field
+			out.putInt(authBlocks[i].getTimestamp());
+			encodeString(out, authBlocks[i].getSpi());
+			out.put(authBlocks[i].getSig());
+			// fill in the length
+			out.putShort(pos + 2, (short) (out.position() - pos));
+		}
+	}
+
+	
+	public void sign(final String spiStr) throws ServiceLocationException {
+		List spiList = SLPUtils.stringToList(spiStr, ",");
+		authBlocks = new AuthenticationBlock[spiList.size()];
+		for (int k = 0; k < spiList.size(); k++) {
+			int timestamp = SLPUtils.getTimestamp();
+
+			String spi = (String) spiList.get(k);
+			byte[] data = getAuthData(spi, timestamp);
+			byte[] sig;
+			try {
+				sig = AuthenticationBlock.sign(spi,data);
+			} catch (Exception e) {
+				//SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+				throw new ServiceLocationException(
+						ServiceLocationException.AUTHENTICATION_FAILED,
+						"Could not sign data");
+			}
+			
+			
+			authBlocks[k] = new AuthenticationBlock(timestamp,spi,sig);
+		}
+	}
+	
+	public boolean verify() {
+		try {
+			for (int i = 0; i < authBlocks.length; i++) {
+
+				if (authBlocks[i].verify(getAuthData(authBlocks[i].getSpi(),
+						authBlocks[i].getTimestamp()))) {
+					return true;
+				}
+			}
+			return false;
+		} catch (ServiceLocationException sle){
+			return false;
+		}
+	}
+	
+	
+	private byte[] getAuthData(final String spiStr, final int timestamp)
+	throws ServiceLocationException {
+try {
+	ByteArrayOutputStream bos = new ByteArrayOutputStream();
+	DataOutputStream dos = new DataOutputStream(bos);
+	dos.writeUTF(spiStr);
+	dos.writeUTF(attributeList);
+	dos.writeInt(timestamp);
+	return bos.toByteArray();
+} catch (IOException ioe) {
+	throw new ServiceLocationException(
+			ServiceLocationException.INTERNAL_SYSTEM_ERROR, ioe
+					.getMessage());
+}
+}
+
+
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/AttributeListExtension.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,96 @@
+/* 
+ *   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.directory.slp.extensions;
+
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.impl.SLPCore;
+import org.apache.mina.core.buffer.IoBuffer;
+
+
+
+/**
+ * The select extension as defined in RFC 3421
+ * 
+ * (processing currently not yet implemented)
+ * 
+ * @author Lorenz Breu
+ */
+public class SelectExtension extends AbstractExtension{
+
+	
+	/*
+	 *  0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | Select Extension ID = 0x4002  |  Next Extension Offset (NEO)  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | NEO, cont'd   |      Number of URL Entries    |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 */
+	
+	
+	// The number of entries to be returned
+	private short numberOfEntries = 0;
+
+	public SelectExtension(){
+		super(SELECT_EXTENSION);
+	}
+	
+	public SelectExtension(short n){
+		super(SELECT_EXTENSION);
+		numberOfEntries = n;
+	}
+	
+	@Override
+	protected void decodeBody(IoBuffer buf, short id, int nextOffset) throws Exception {
+		numberOfEntries = buf.getShort();
+		
+	}
+
+	@Override
+	public void encodeBody(IoBuffer buf) {
+		try {
+			buf.putShort(numberOfEntries);
+		} catch (Exception e){
+			SLPCore.getPlatform().logDebug("[Extensions]: Error encoding a Select Extension: " + e.getMessage());
+		}
+		
+	}
+
+	@Override
+	public void sign(String spi) throws ServiceLocationException {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public boolean verify() {
+		return true;
+	}
+
+	public short getNumberOfEntries() {
+		return numberOfEntries;
+	}
+
+	public void setNumberOfEntries(short numberOfEntries) {
+		this.numberOfEntries = numberOfEntries;
+	}
+
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SelectExtension.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,97 @@
+/* 
+ *   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.directory.slp.extensions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.impl.SLPCore;
+import org.apache.directory.slp.impl.SLPUtils;
+import org.apache.mina.core.buffer.IoBuffer;
+
+
+/**
+ * The sort extension as defined in RFC 3421
+ * 
+ * (processing currently not yet implemented)
+ * 
+ * @author Lorenz Breu
+ */
+public class SortExtension extends AbstractExtension{
+	
+	/*
+	 *  0                   1                   2                   3
+    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |  Sort Extension ID = 0x4003   |  Next Extension Offset (NEO)  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   | NEO, cont'd   |   length of <sort-key-list>   |<sort-key-list>\
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * 
+	 */
+	
+	// The key list for sorting
+	private List<String> sortKeyList = new ArrayList<String>();
+	
+	public SortExtension(){
+		super(SORT_EXTENSION);
+	}
+	
+	public SortExtension(String sortKeyList){
+		super(SORT_EXTENSION);
+		this.sortKeyList = SLPUtils.stringToList(sortKeyList, ",");
+	}
+
+	@Override
+	protected void decodeBody(IoBuffer buf, short id, int nextOffset) throws Exception {
+		sortKeyList = SLPUtils.stringToList(decodeString(buf), ",");
+		
+	}
+
+	@Override
+	public void encodeBody(IoBuffer buf) {
+		try{
+		encodeString(buf, SLPUtils.arrayToString(SLPUtils.listToStringArray(sortKeyList),","));
+		} catch (Exception e){
+			SLPCore.getPlatform().logDebug("[Extensions]: Error encoding a Sort Extension: " + e.getMessage());
+		}
+	}
+
+	@Override
+	public void sign(String spi) throws ServiceLocationException {
+		return;
+		
+	}
+
+	@Override
+	public boolean verify() {
+		return true;
+	}
+
+	public List<String> getSortKeyList() {
+		return sortKeyList;
+	}
+
+	public void setSortKeyList(List<String> sortKeyList) {
+		this.sortKeyList = sortKeyList;
+	}
+
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/SortExtension.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,60 @@
+/* 
+ *   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.directory.slp.extensions;
+
+import org.apache.mina.core.buffer.IoBuffer;
+
+/**
+ * A placeholder for extensions that are received but not supported
+ * 
+ * @author Lorenz Breu
+ */
+public class UnsupportedExtension extends AbstractExtension{
+
+	public UnsupportedExtension(short id){
+		super(id);
+	}
+
+	@Override
+	protected void decodeBody(IoBuffer buf, short id, int nextOffset) throws Exception {
+		
+		
+	}
+
+	@Override
+	public void encodeBody(IoBuffer buf) {
+		
+		
+	}
+	
+	
+	public boolean verify(){
+		return true;
+	}
+	
+	public void sign(String spi){
+		
+	}
+	
+	
+	
+
+
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/extensions/UnsupportedExtension.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,96 @@
+/* 
+ *   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.directory.slp.impl;
+
+import org.apache.directory.slp.ServiceStore;
+import org.apache.directory.slp.impl.da.DirectoryAgentImpl;
+import org.apache.directory.slp.impl.da.SimpleServiceStore;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Bundle Activator
+ * 
+ * @author Jan S. Rellermeyer
+ */
+public class Activator implements BundleActivator {
+
+	/**
+	 * 
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(final BundleContext context) throws Exception {
+
+		// create the platform abstraction layer but do not initialize!!!
+		SLPCore.platform = new OSGiPlatformAbstraction(context);
+
+		// register the service factories so each consumer gets its own Locator/Activator instance
+		context.registerService("ch.ethz.iks.slp.Advertiser", new ServiceFactory() {
+			public Object getService(Bundle bundle, ServiceRegistration registration) {
+				SLPCore.initSA();
+				return new AdvertiserImpl();
+			}
+			public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+			}
+		}, null);
+		context.registerService("ch.ethz.iks.slp.Locator", new ServiceFactory() {
+			public Object getService(Bundle bundle, ServiceRegistration registration) {
+				SLPCore.init();
+				return new LocatorImpl();
+			}
+			public void ungetService(Bundle bundle,	ServiceRegistration registration, Object service) {
+			}
+		}, null);
+		
+		
+		
+		
+        final ServiceStore finalStore = new SimpleServiceStore();
+		context.registerService("ch.ethz.iks.slp.DirectoryAgent", new ServiceFactory() {
+			public Object getService(Bundle bundle, ServiceRegistration registration) {
+				SLPCore.initDA(finalStore);
+				return new DirectoryAgentImpl();
+			}
+			public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+			}
+		}, null);
+		
+		
+//		context.registerService("ch.ethz.iks.slp.DirectoryAgent", new ServiceFactory() {
+//			public Object getService(Bundle bundle, ServiceRegistration registration) {
+//				SLPCore.initDA(new SimpleServiceStore());
+//				return new DirectoryAgentImpl();
+//			}
+//			public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+//			}
+//		}, null);
+	}
+
+	/**
+	 * 
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(final BundleContext context) throws Exception {
+		
+	}
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/Activator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,345 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.directory.slp.Advertiser;
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.ServiceURL;
+import org.apache.directory.slp.messages.ServiceAcknowledgementMessage;
+import org.apache.directory.slp.messages.ServiceDeregistrationMessage;
+import org.apache.directory.slp.messages.ServiceRegistrationMessage;
+
+/**
+ * Implementation of the Advertiser that provides SLP SA functionality. If the
+ * configuration does not have to support SA functionalities, this class does
+ * not have to be included in the distribution.
+ * 
+ * @author Jan S. Rellermeyer
+ */
+public final class AdvertiserImpl implements Advertiser {
+
+	/**
+	 * the locale of this instance. Will be used for all messages created by
+	 * this Advertiser instance.
+	 */
+	private Locale locale;
+
+	/**
+	 * Constructor for AdvertiserImpl.
+	 */
+	public AdvertiserImpl() {
+		locale = SLPCore.DEFAULT_LOCALE;
+	}
+
+	/**
+	 * Constructor for AdvertiserImpl.
+	 * 
+	 * @param theLocale
+	 *            Locale.
+	 */
+	public AdvertiserImpl(final Locale locale) {
+		this.locale = locale;
+	}
+
+	/**
+	 * Get the locale of this instance.
+	 * 
+	 * @return Locale.
+	 * @see Advertiser#getLocale()
+	 */
+	public Locale getLocale() {
+		return locale;
+	}
+
+	/**
+	 * Set the locale of this instance.
+	 * 
+	 * @param locale
+	 *            the Locale.
+	 * @see Advertiser#setLocale()
+	 */
+	public void setLocale(final Locale locale) {
+		this.locale = locale;
+	}
+
+	/**
+	 * register a new service with the framework.
+	 * 
+	 * @param url
+	 *            the ServiceURL of the service.
+	 * @param attributes
+	 *            a Dictionary of attributes.
+	 * @throws ServiceLocationException
+	 *             if the registration has failed for any reason.
+	 * @see Advertiser#register(ServiceURL, Dictionary)
+	 */
+	public void register(final ServiceURL url, final Dictionary attributes)
+			throws ServiceLocationException {
+		register(url, null, attributes);
+	}
+
+	/**
+	 * register a new service with the framework using scopes.
+	 * 
+	 * @param url
+	 *            the ServiceURL of the service.
+	 * @param scopes
+	 *            a List of scopes.
+	 * @param attributes
+	 *            a Dictionary of attributes.
+	 * @throws ServiceLocationException
+	 *             if the registration has failed for any reason.
+	 * @see Advertiser#register(ServiceURL, List, Dictionary)
+	 */
+	public void register(final ServiceURL url, final List scopes,
+			final Dictionary attributes) throws ServiceLocationException {
+		ServiceRegistrationMessage reg = new ServiceRegistrationMessage();
+		reg.setServiceURL(url);
+		reg.setServiceType(url.getServiceType());
+		if (scopes != null) {
+			reg.setScopes((String[]) scopes.toArray());
+		}
+		reg.setAttrList((String[]) SLPUtils.dictToAttrList(attributes).toArray(
+				new String[] {}));
+		reg.setLocale(locale);
+		InetAddress addr;
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			addr = SLPCore.getMyIP();
+		}
+		ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+				.sendUnicastMessage(reg, new InetSocketAddress(addr
+						.getHostAddress(), SLPCore.SLP_PORT), true);
+
+		if (ack == null) {
+			throw new ServiceLocationException((short) 1, "Registration failed");
+		}
+		if (ack.getErrorCode() != 0) {
+			throw new ServiceLocationException((short) ack.getErrorCode(),
+					"Registration failed");
+		}
+	}
+
+	/**
+	 * update an existing registration using scopes. This will replace all
+	 * attributes that are already registered and add those that are not. If
+	 * security is enabled, this will fail.
+	 * 
+	 * @param url
+	 *            the ServiceURL of the service.
+	 * @param scopes
+	 *            a List of scopes.
+	 * @param attributes
+	 *            a Dictionary of attributes.
+	 * @throws ServiceLocationException
+	 *             if the registration has failed for any reason.
+	 * @see Advertiser#register(ServiceURL, List, Dictionary)
+	 */
+	public void update(final ServiceURL url, final List scopes,
+			final Dictionary attributes) throws ServiceLocationException {
+		if (SLPCore.CONFIG.getSecurityEnabled()) {
+			// in a security enabled setting, updating fails as the auth blocks
+			// would be invalid.
+			throw new ServiceLocationException(
+					ServiceLocationException.AUTHENTICATION_FAILED,
+					"Cannot update an entry with auth blocks set. Need to register anew.");
+		}
+		ServiceRegistrationMessage reg = new ServiceRegistrationMessage();
+		reg.setServiceURL(url);
+		reg.setServiceType(url.getServiceType());
+		if (scopes != null) {
+			reg.setScopes((String[]) scopes.toArray());
+		}
+		reg.setAttrList((String[]) SLPUtils.dictToAttrList(attributes).toArray(
+				new String[] {}));
+		reg.setLocale(locale);
+		reg.setFresh(false);
+		InetAddress addr;
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			addr = SLPCore.getMyIP();
+		}
+		ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+				.sendUnicastMessage(reg, new InetSocketAddress(addr
+						.getHostAddress(), SLPCore.SLP_PORT), true);
+
+		if (ack == null) {
+			throw new ServiceLocationException((short) 1, "Registration failed");
+		}
+		if (ack.getErrorCode() != 0) {
+			throw new ServiceLocationException((short) ack.getErrorCode(),
+					"Registration failed");
+		}
+	}
+
+	/**
+	 * deregister a service.
+	 * 
+	 * @param url
+	 *            the ServiceURL of the service.
+	 * @throws ServiceLocationException
+	 *             if the deregistration has failed for any reason.
+	 * @see Advertiser#deregister(ServiceURL)
+	 */
+	public void deregister(final ServiceURL url)
+			throws ServiceLocationException {
+		deregister(url, null);
+	}
+
+	/**
+	 * deregister a service in some scopes.
+	 * 
+	 * @param url
+	 *            the ServiceURL of the service.
+	 * @param scopes
+	 *            the scopes.
+	 * @throws ServiceLocationException
+	 *             if the deregistration has failed for any reason.
+	 * @see Advertiser#deregister(ServiceURL, List)
+	 * @since 0.7.1
+	 */
+
+	public void deregister(final ServiceURL url, final List<String> scopes)
+			throws ServiceLocationException {
+		ServiceDeregistrationMessage dereg = new ServiceDeregistrationMessage();
+		dereg.setServiceURL(url);
+		if (scopes != null && !scopes.isEmpty()) {
+			dereg.setScopes((String[]) scopes.toArray(new String[] {}));
+		}
+		dereg.setLocale(locale);
+		InetAddress addr;
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			addr = SLPCore.getMyIP();
+		}
+		int port = SLPCore.SLP_PORT;
+		ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+				.sendUnicastMessage(dereg, new InetSocketAddress(addr
+						.getHostAddress(), port), true);
+		if (ack == null) {
+			throw new ServiceLocationException(
+					ServiceLocationException.INTERNAL_SYSTEM_ERROR,
+					"Deregistration failed");
+		}
+		if (ack.getErrorCode() != 0) {
+			throw new ServiceLocationException((short) ack.getErrorCode(),
+					"Deregistration failed");
+		}
+	}
+
+	/**
+	 * add Attributes to a registered service. Existing attributes will be
+	 * overwritten.
+	 * 
+	 * @see Advertiser#addAttributes(ServiceURL, Dictionary)
+	 * @param url
+	 *            the serviceURL
+	 * @param attributes
+	 *            the attributes to add.
+	 * @throws ServiceLocationException
+	 * 
+	 */
+	public void addAttributes(final ServiceURL url, final Dictionary attributes)
+			throws ServiceLocationException {
+		update(url, null, attributes);
+	}
+
+	/**
+	 * deletes attributes from a registration.
+	 * 
+	 * @see Advertiser#deleteAttributes(ServiceURL, Dictionary)
+	 * @param url
+	 *            the serviceURL.
+	 * @param attributes
+	 *            the attributes to delete.
+	 * @throws ServiceLocationException
+	 * 
+	 */
+	public void deleteAttributes(final ServiceURL url,
+			final Dictionary attributes) throws ServiceLocationException {
+
+		// if security is enabled, this is not possible...
+		if (SLPCore.CONFIG.getSecurityEnabled()) {
+			throw new ServiceLocationException(
+					ServiceLocationException.AUTHENTICATION_FAILED,
+					"can not delete attributes when security is enabled");
+		}
+
+		// build the deregistration message
+		ServiceDeregistrationMessage dereg = new ServiceDeregistrationMessage();
+		dereg.setServiceURL(url);
+		dereg.setLocale(locale);
+		// set the tags!
+		Enumeration keys = attributes.keys();
+		List<String> tags = new ArrayList<String>();
+		while (keys.hasMoreElements()) {
+			tags.add(keys.nextElement().toString());
+		}
+		dereg.setTags(tags.toArray(new String[tags.size()]));
+
+		// check if tags have been set
+		if (dereg.getTags().length < 1) {
+			throw new ServiceLocationException(
+					ServiceLocationException.INTERNAL_SYSTEM_ERROR,
+					"This would lead to a complete deregistration...");
+		}
+
+		InetAddress addr;
+		try {
+			addr = InetAddress.getLocalHost();
+		} catch (UnknownHostException e) {
+			addr = SLPCore.getMyIP();
+		}
+		int port = SLPCore.SLP_PORT;
+		ServiceAcknowledgementMessage ack = (ServiceAcknowledgementMessage) SLPCore
+				.sendUnicastMessage(dereg, new InetSocketAddress(addr
+						.getHostAddress(), port), true);
+		if (ack == null) {
+			throw new ServiceLocationException(
+					ServiceLocationException.INTERNAL_SYSTEM_ERROR,
+					"Attribute deletion failed");
+		}
+		if (ack.getErrorCode() != 0) {
+			throw new ServiceLocationException((short) ack.getErrorCode(),
+					"Attribute deletion failed");
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see ch.ethz.iks.slp.Advertiser#shutdown()
+	 */
+	public void shutdown() {
+		SLPCore.shutdownAdvertiser();
+	}
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AdvertiserImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,257 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.slp.AttributeReplyFuture;
+import org.apache.directory.slp.SLPAttribute;
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.extensions.AbstractExtension;
+import org.apache.directory.slp.extensions.UnsupportedExtension;
+import org.apache.directory.slp.messages.AbstractSLPReplyMessage;
+import org.apache.directory.slp.messages.AttributeReplyMessage;
+
+/**
+ * 
+ * @author Lorenz Breu
+ */
+public class AttributeReplyFutureImpl extends NonThreadedReplyFuture implements
+		AttributeReplyFuture {
+
+	
+//	List of responses (i.e. message results)
+	private final List<SLPAttributeImpl> attributes = new ArrayList<SLPAttributeImpl>();
+	
+	// next attribute to return when next() is called
+	private int nextAttributePosition = 0;
+	
+	/**
+	 * Creates a new AttributeReplyFuture with a timeout of 5x the WaitTime in SLPConfiguration
+	 */
+	public AttributeReplyFutureImpl(){
+		super(SLPCore.CONFIG.getWaitTime()*5);
+	}
+	
+	
+	/**
+	 * Creates a new AttributeReplyFuture with the specified lifetime (in ms)
+	 * 
+	 * @param lifetime
+	 * 			The time until the ReplyFuture is considered done in ms
+	 */
+	public AttributeReplyFutureImpl(long lifetime){
+		super(lifetime);
+	}
+	
+	
+	
+	/**
+	 * Creates a new AttributeReplyFuture with the specified lifetime (in ms) expecting responses
+	 * for the specified scopes.
+	 * 
+	 * @param lifetime
+	 * 			The lifetime in ms
+	 * @param scopes
+	 * 			The scopes for which replies are expected. used for completion checks
+	 */			
+	public AttributeReplyFutureImpl(long lifetime,List<String> scopes){
+		super(lifetime, scopes);
+	}
+	
+	@Override
+	public void add(AbstractSLPReplyMessage reply){
+
+		if (reply==null || reply.getErrorCode()!=0){
+			return;
+		}
+		if (done){
+			// this reply is coming in too late...
+			return;
+		}
+		
+		synchronized (responders){
+			if (!responders.contains(reply.getSource())) {
+				responders.add(reply.getSource());
+			} else {
+				return;
+			}
+		}
+		
+		if (reply instanceof AttributeReplyMessage){
+			for (String s : reply.getResult()){
+				try{
+					String[] fields = s.split("=");
+					String at_name=fields[0];
+					if (at_name.startsWith("(")){
+						at_name=at_name.substring(1);
+					}
+					if (at_name.endsWith(")")){
+						at_name=at_name.substring(0, at_name.length()-1);
+					}
+					if (fields.length==1){
+						synchronized(attributes){
+							attributes.add(new SLPAttributeImpl(at_name));
+						}
+					} else {
+						List<String> vals = SLPUtils.stringToList(fields[1].substring(0,fields[1].length()-1), ",");
+						synchronized(attributes){
+							attributes.add(new SLPAttributeImpl(at_name,vals));
+						}
+					}
+					
+					
+
+				} catch (ServiceLocationException sle){
+					continue;
+				}
+			}
+			processExtensions(reply);
+			
+		}
+		
+		
+		//stick to the basic behaviour...
+		synchronized(responses){
+			List<String> res = reply.getResultAsList();
+			if (res!=null && res.size()>0){
+				List<String> resp = reply.getResultAsList();
+				for (String s: resp){
+					if (!responses.contains(s)){
+						responses.add(s);
+					}
+				}
+				responses.notifyAll();
+			}
+		}
+		
+	}
+	
+	/**
+	 * Process the extensions
+	 * 
+	 * @param reply
+	 * 			The reply message possibly containing extensions
+	 * 
+	 */
+	private void processExtensions(AbstractSLPReplyMessage reply){
+		for (AbstractExtension ae : reply.getExtensions()){
+			if (ae instanceof UnsupportedExtension){
+				return;
+			}
+			switch (ae.getId()){
+			
+				
+				
+			}
+		}
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see ch.ethz.iks.slp.AttributeReplyFuture#nextAttribute()
+	 */
+	public SLPAttribute nextAttribute(){
+		// NOTE: a future is currently only read by one consumer (i.e. LocatorImpl) and therefor a single
+		// position marker is sufficient. Also the data containers holding responses must add new elements to the end.
+		synchronized(attributes){
+			while (!done){
+				if (attributes.size()>nextAttributePosition){
+					return attributes.get(nextAttributePosition++);
+				}
+				try{
+					attributes.wait(timeout-System.currentTimeMillis()+1000);
+				} catch (InterruptedException e){
+					
+				}
+			}
+			if (attributes.size()>nextAttributePosition){
+				return attributes.get(nextAttributePosition++);
+			}
+			return null;
+		}
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see ch.ethz.iks.slp.AttributeReplyFuture#getResultAttributes()
+	 */
+	public List<SLPAttribute> getResultAttributes(){
+		while (!done){
+			synchronized (donelock){
+				try {
+					donelock.wait();
+				} catch (InterruptedException ie){
+					
+				}
+			}
+		}
+		return mergeAttributes();
+	}
+	
+
+	/**
+	 *	Merges the SLPAttributes of the same type. 
+	 *	Must be called only when the reply future is done, i.e. all responses are in.
+	 * 
+	 * @return
+	 */
+	private List<SLPAttribute> mergeAttributes(){
+		
+			List<SLPAttributeImpl> t_attributes = new ArrayList<SLPAttributeImpl>(attributes);
+			List<SLPAttribute> merged = new ArrayList<SLPAttribute>();
+			List<String> keywords = new ArrayList<String>();
+			while (!t_attributes.isEmpty()){
+				SLPAttributeImpl a = t_attributes.get(0);
+				if (a.isKeyword()){
+					if (!keywords.contains(a.getName())){
+						merged.add(a);
+						keywords.add(a.getName());
+					}				
+					t_attributes.remove(0);
+				} else {
+					List<SLPAttributeImpl> remove = new ArrayList<SLPAttributeImpl>();
+					for (int i=1;i<t_attributes.size();i++){
+						SLPAttributeImpl b = t_attributes.get(i);
+						if (b.getName().equals(a.getName()) && b.getType()==a.getType()){
+							a.merge(b);
+							remove.add(b);
+						}
+					}
+					merged.add(a);
+					t_attributes.remove(a);
+					for (SLPAttributeImpl j:remove){
+						t_attributes.remove(j);
+					}
+				}
+			}
+			
+			
+			return new ArrayList<SLPAttribute>(merged);
+		
+		
+		
+		
+	}
+
+
+	
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AttributeReplyFutureImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,179 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.directory.slp.ServiceLocationException;
+
+/**
+ * Authentication support for service URLs.
+ * 
+ * @author Jan S. Rellermeyer
+ */
+public class AuthenticatedServiceURL {
+
+	int lifetime = 0;
+	
+	/**
+	 * the authentication blocks.
+	 */
+	private AuthenticationBlock[] authBlocks;
+
+	/**
+	 * set the authentication blocks.
+	 * 
+	 * @param authBlocks
+	 *            the authentication blocks.
+	 */
+	public void setAuthBlocks(final AuthenticationBlock[] authBlocks) {
+		this.authBlocks = authBlocks;
+	}
+
+	public AuthenticationBlock[] getAuthBlocks() {
+		return authBlocks;
+	}
+
+	
+	
+	
+	/**
+	 * verify the authentication blocks.
+	 * 
+	 * Copied over to the MINA port from the original jSLP implementation, untested
+	 */
+	public void verify() throws ServiceLocationException {
+		if (authBlocks.length == 0) {
+			return;
+		}
+		for (int i = 0; i < authBlocks.length; i++) {
+			byte[] data = getAuthData(authBlocks[i].getSpi(), authBlocks[i]
+					.getTimestamp());
+			if (authBlocks[i].verify(data)) {
+				return;
+			}
+		}
+		// TODO: improve
+		throw new ServiceLocationException(
+				ServiceLocationException.AUTHENTICATION_FAILED, "");
+	}
+
+	/**
+	 * get the byte representation of the authentication data.
+	 * 
+	 * @param spi
+	 *            the SPI string as defined in RFC 2608
+	 * @param timestamp
+	 *            a timestamp as defined in RFC 2608
+	 * @return a byte array.
+	 * @throws ServiceLocationException
+	 *             in case of internal errors.
+	 */
+	private byte[] getAuthData(final String spi, final int timestamp)
+			throws ServiceLocationException {
+		try {
+			final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			final DataOutputStream dos = new DataOutputStream(bos);
+
+			byte[] temp = spi.getBytes();
+			dos.writeShort(temp.length);
+			dos.write(temp);
+			temp = toString().getBytes();
+			dos.writeShort(temp.length);
+			dos.write(temp);
+			dos.writeInt(timestamp);
+			return bos.toByteArray();
+		} catch (IOException ioe) {
+			throw new ServiceLocationException(
+					ServiceLocationException.INTERNAL_SYSTEM_ERROR, ioe
+							.getMessage());
+		}
+	}
+	
+	/**
+	 * sign the ServiceURL.
+	 * 
+	 * @param spiList
+	 *            the List of SPIs
+	 * @throws ServiceLocationException
+	 *             in case of IO errors.
+	 */
+	public final void sign(final List spiList)
+			throws ServiceLocationException {
+		authBlocks = new AuthenticationBlock[spiList.size()];
+		for (int k = 0; k < spiList.size(); k++) {
+			int timestamp = SLPUtils.getTimestamp();
+			timestamp += lifetime;
+
+			String spi = (String) spiList.get(k);
+			byte[] data = getAuthData(spi, timestamp);
+			byte[] sig;
+			try {
+				sig = AuthenticationBlock.sign(spi,data);
+			} catch (Exception e) {
+				//SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+				throw new ServiceLocationException(
+						ServiceLocationException.AUTHENTICATION_FAILED,
+						"Could not sign data");
+			}
+			authBlocks[k] = new AuthenticationBlock(timestamp,spi,sig);
+			
+		}
+	}
+	
+	/**
+	 * sign the ServiceURL.
+	 * 
+	 * Copied over to the MINA port from the original jSLP implementation, untested
+	 * 
+	 * Type mismatch between the original jSLP (all Lists) and the MINA codecs (all String[])
+	 * required this overload.
+	 * 
+	 * @param spiList
+	 *            the String[] of SPIs
+	 * @throws ServiceLocationException
+	 *             in case of IO errors.
+	 */
+	public final void sign (final String[] spiList) throws ServiceLocationException{
+		authBlocks = new AuthenticationBlock[spiList.length];
+		for (int k = 0; k< spiList.length;k++){
+			int timestamp = SLPUtils.getTimestamp();
+			timestamp += lifetime;
+
+			String spi = (String) spiList[k];
+			byte[] data = getAuthData(spi, timestamp);
+			byte[] sig;
+			try {
+				sig = AuthenticationBlock.sign(spi,data);
+			} catch (Exception e) {
+				//SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+				throw new ServiceLocationException(
+						ServiceLocationException.AUTHENTICATION_FAILED,
+						"Could not sign data");
+			}
+			authBlocks[k] = new AuthenticationBlock(timestamp,spi,sig);
+		}
+	}
+	
+
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticatedServiceURL.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,169 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+
+import org.apache.directory.slp.ServiceLocationException;
+
+
+/**
+ * Authentication block.
+ * 
+ * @author Jan S. Rellermeyer
+ */
+public class AuthenticationBlock {
+
+	/**
+	 * the BSD code for DSA.
+	 */
+	public static final short BSD_DSA = 0x0002;
+
+	/**
+	 * the timestamp.
+	 */
+	private int timestamp;
+
+	/**
+	 * the signature.
+	 */
+	private byte[] sig = null;
+
+	/**
+	 * the SPI.
+	 */
+	private String spi = null;
+
+	public AuthenticationBlock(final int timestamp, final String spi,
+			final byte[] sig) {
+		this.timestamp = timestamp;
+		this.spi = spi;
+		this.sig = sig;
+	}
+
+	public int getTimestamp() {
+		return timestamp;
+	}
+
+	public String getSpi() {
+		return spi;
+	}
+	
+	
+	/**
+	 * sign the AuthenticationBlock.
+	 * 
+	 * @throws ServiceLocationException
+	 *             in case of processing errors.
+	 */
+	public static byte[] sign(String spi,byte[] data) throws ServiceLocationException {
+		try {
+			PrivateKey privateKey = SLPCore.CONFIG.getPrivateKey(spi);
+			SLPCore.platform.logDebug("Signing with SPI: " + spi);
+			Signature signature = Signature.getInstance("SHA1withDSA");
+			signature.initSign(privateKey);
+			signature.update(data);
+			byte[] sig = signature.sign();
+			return sig;
+		} catch (Exception e) {
+			SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+			throw new ServiceLocationException(
+					ServiceLocationException.AUTHENTICATION_FAILED,
+					"Could not sign data");
+		}
+	}
+
+	
+	
+	
+
+	/**
+	 * verify the authBlock.
+	 * 
+	 * @param verData
+	 *            the auth data.
+	 * @return true if verification suceeds.
+	 * @throws ServiceLocationException
+	 *             in case of IO errors.
+	 */
+	public boolean verify(final byte[] verData) throws ServiceLocationException {
+		try {
+			PublicKey publicKey = SLPCore.CONFIG.getPublicKey(spi);
+
+			Signature signature = Signature.getInstance("SHA1withDSA");
+			signature.initVerify(publicKey);
+			signature.update(verData);
+			boolean success = signature.verify(sig);
+			SLPCore.platform.logDebug((success ? "Verified with SPI: "
+						: "Verification failed with SPI: ")
+						+ spi);
+
+			return success;
+		} catch (Exception e) {
+			SLPCore.platform.logError(e.getMessage(), e.fillInStackTrace());
+			throw new ServiceLocationException(
+					ServiceLocationException.AUTHENTICATION_FAILED,
+					"Could not verify data with SPI: " + spi);
+		}
+	}
+
+	public byte[] getSig() {
+		return sig;
+	}
+	
+	/**
+	 * calculates the length of this auth block.
+	 * 
+	 * @return the length.
+	 */
+	public int getLength() {
+		return 2 // BSD
+				+ 2 // Block length
+				+ 4 // timestamp
+				+ 2 // spi length
+				+ spi.getBytes().length // spi
+				+ sig.length; // signature
+	}
+	
+	/**
+	 * get the bytes.
+	 * 
+	 * @return the bytes.
+	 * @throws IOException
+	 *             in case of IO errors.
+	 */
+	public void write(final DataOutputStream out) throws IOException {
+		out.writeShort(BSD_DSA); // BSD
+		out.writeShort((short) getLength());
+		out.writeInt(timestamp);
+		byte[] temp = spi.getBytes();
+		out.writeShort(temp.length);
+		out.write(temp);
+		out.write(sig);
+	}
+	
+	
+	
+	
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/AuthenticationBlock.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,537 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.directory.slp.Advertiser;
+import org.apache.directory.slp.AttributeReplyFuture;
+import org.apache.directory.slp.Locator;
+import org.apache.directory.slp.ReplyFuture;
+import org.apache.directory.slp.ServiceLocationException;
+import org.apache.directory.slp.ServiceReplyFuture;
+import org.apache.directory.slp.ServiceType;
+import org.apache.directory.slp.ServiceURL;
+import org.apache.directory.slp.extensions.AttributeListExtension;
+import org.apache.directory.slp.messages.AbstractSLPReplyMessage;
+import org.apache.directory.slp.messages.AbstractSLPRequestMessage;
+import org.apache.directory.slp.messages.AttributeRequestMessage;
+import org.apache.directory.slp.messages.ServiceRequestMessage;
+import org.apache.directory.slp.messages.ServiceTypeRequestMessage;
+//import com.sun.slamd.stat.CategoricalTracker;
+
+/**
+ * Implementation of the Locator interface. If the configuration does not have
+ * to provide UA functionalities, this class does not have to be included in the
+ * distribution.
+ * 
+ * @author Jan S. Rellermeyer
+ */
+public final class LocatorImpl implements Locator {
+	/**
+	 * 
+	 */
+	private Locale locale;
+
+	// If true then Service Requests include the Attribute List Extension
+	private boolean useAttributeListExtension = false;
+
+	// The thread pool for lookups
+	private static ExecutorService threadPool = Executors.newCachedThreadPool();
+
+	/**
+	 * create a new LocatorImpl instance.
+	 */
+	public LocatorImpl() {
+		locale = SLPCore.DEFAULT_LOCALE;
+	}
+
+	/**
+	 * create a new LocatorImpl instance.
+	 * 
+	 * @param theLocale
+	 *            the Locale for this instance.
+	 */
+	public LocatorImpl(final Locale locale) {
+		this.locale = locale;
+	}
+
+	/**
+	 * returns the locale for this instance.
+	 * 
+	 * @return the Locale.
+	 */
+	public Locale getLocale() {
+		return locale;
+	}
+
+	/**
+	 * Set the locale of this instance.
+	 * 
+	 * @param locale
+	 *            the Locale.
+	 * @see Advertiser#setLocale()
+	 */
+	public void setLocale(final Locale locale) {
+		this.locale = locale;
+	}
+
+	/**
+	 * find the service types.
+	 * 
+	 * @param namingAuthority
+	 *            the naming authority.
+	 * @param scopes
+	 *            the scopes.
+	 * @return a ServiceLocationEnumeration over the results.
+	 * @throws ServiceLocationException
+	 *             if something goes wrong.
+	 * @see Locator#findServiceTypes(String, List)
+	 */
+	public ReplyFuture findServiceTypes(
+			final String namingAuthority, final List<String> scopes)
+	throws ServiceLocationException {
+		ServiceTypeRequestMessage srvTypeReq = new ServiceTypeRequestMessage();
+		srvTypeReq.setNamingAuthority(namingAuthority);
+		if (scopes!=null){
+			if (scopes.size()>0){
+				srvTypeReq.setScopes(SLPUtils.listToStringArray(scopes));
+			}
+		}
+		srvTypeReq.setLocale(locale);
+		return sendRequest(srvTypeReq,scopes);
+	}
+
+
+
+	/**
+	 * find services.
+	 * 
+	 * @param type
+	 *            the service type.
+	 * @param scopes
+	 *            the scopes.
+	 * @param searchFilter
+	 *            an LDAP filter expression.
+	 * @return a ServiceLocationEnumeration over the results.
+	 * @throws ServiceLocationException
+	 *             if something goes wrong.
+	 * @see Locator#findAttributes(ServiceType, List, List)
+	 */
+	public ServiceReplyFuture findServices(final ServiceType type,
+			final List<String> scopes, final String searchFilter)
+	throws ServiceLocationException {
+		try {
+			ServiceRequestMessage srvReq = new ServiceRequestMessage();
+			srvReq.setServiceType(type);
+			if (scopes!=null){
+				if (scopes.size()>0){
+					srvReq.setScopes(SLPUtils.listToStringArray(scopes));
+				}
+			}
+			srvReq.setPredicate(searchFilter);
+			srvReq.setLocale(locale);
+
+			if (useAttributeListExtension){
+				srvReq.addExtension(new AttributeListExtension("",""));
+			}
+
+			if (SLPCore.CONFIG.getSecurityEnabled()){
+				srvReq.setSPIs(SLPUtils.stringToStringArray(SLPCore.CONFIG.getSPI(), ","));
+			}
+
+			return (ServiceReplyFutureImpl) sendRequest(srvReq,scopes);
+		} catch (IllegalArgumentException ise) {
+
+			throw new ServiceLocationException(
+					ServiceLocationException.INTERNAL_SYSTEM_ERROR, ise
+					.getMessage()
+					+ ": " + searchFilter);
+		}
+	}
+
+
+	/**
+	 * find attributes by service URL.
+	 * 
+	 * @param url
+	 *            the ServiceURL of the service.
+	 * @param scopes
+	 *            a List of scoped to be included.
+	 * @param attributeIds
+	 *            a List of attributes for which the values should be returned,
+	 *            if they exist.
+	 * @return ServiceLocationEnumeration over the results.
+	 * @throws ServiceLocationException
+	 *             in case of network errors etc.
+	 * @see Locator#findAttributes(ServiceURL, List, List)
+	 */
+	public AttributeReplyFuture findAttributes(final ServiceURL url,
+			final List scopes, final List attributeIds)
+	throws ServiceLocationException {
+		AttributeRequestMessage attrReq = new AttributeRequestMessage();
+		attrReq.setServiceURL(url);
+		if (scopes!=null){
+			if (scopes.size()>0){
+				attrReq.setScopes(SLPUtils.listToStringArray(scopes));
+			}
+		}
+		attrReq.setLocale(locale);
+		attrReq.setTags(SLPUtils.listToStringArray(attributeIds));
+		return findAttributes(attrReq);
+	}
+
+	/**
+	 * find attributes by service type.
+	 * 
+	 * @param type
+	 *            the service type.
+	 * @param scopes
+	 *            the scopes.
+	 * @param attributeIds
+	 *            a List of attributes for which the values should be returned,
+	 *            if they exist.
+	 * @return a ServiceLocationEnumeration over the results.
+	 * @throws ServiceLocationException
+	 *             if something goes wrong.
+	 * @see Locator#findAttributes(ServiceType, List, List)
+	 */
+	public AttributeReplyFuture findAttributes(final ServiceType type,
+			final List scopes, final List attributeIds)
+	throws ServiceLocationException {
+		AttributeRequestMessage attrReq = new AttributeRequestMessage();
+		attrReq.setServiceURL(new ServiceURL(type,ServiceURL.LIFETIME_DEFAULT));
+		if (scopes!=null){
+			if (scopes.size()>0){
+				attrReq.setScopes(SLPUtils.listToStringArray(scopes));
+			}
+		}
+		attrReq.setLocale(locale);
+		attrReq.setTags(SLPUtils.listToStringArray(attributeIds));
+		return findAttributes(attrReq);
+	}
+
+
+	/* (non-Javadoc)
+	 * @see ch.ethz.iks.slp.Locator#listenOnSLPPort()
+	 */
+	public void listenOnSLPPort() throws ServiceLocationException {
+		SLPCore.initializeListeners();
+	}
+
+
+
+	/**
+	 * common method that handles a predefined AttributeRequest.
+	 * 
+	 * @param attReq
+	 *            the AttributeRequest.
+	 * @return the resulting Attributes as String.
+	 * @throws ServiceLocationException
+	 *             in case of network errors.
+	 */
+	private AttributeReplyFuture findAttributes(
+			final AttributeRequestMessage attReq) throws ServiceLocationException {
+		return (AttributeReplyFuture) sendRequest(attReq,SLPUtils.arrayToList(attReq.getScopes()));
+	}
+
+
+//	public void shutdown(){
+//		SLPCore.shutdownUserAgent();
+//	}
+
+
+
+
+
+	/**
+	 * send a request. Uses direct communication to a DA or multicast
+	 * convergence, if no DA is known for the specific scope. mcc is ignored when sufficient results are in
+	 * 
+	 * @param req
+	 *            the request.
+	 * @param scopeList
+	 *            the scopes.
+	 * @param numberOfResults
+	 * 			  returns when this number of results have been acquired or the mcc ends
+	 * @return the list of results.
+	 * @throws ServiceLocationException
+	 *             if something goes wrong.
+	 */
+	private ReplyFuture sendRequest(final AbstractSLPRequestMessage req, final List<String> scopeList)
+	throws ServiceLocationException {
+		List<String> scopes = scopeList != null ? scopeList : SLPUtils.stringToList(SLPCore.CONFIG.getScopes(),",");
+		NonThreadedReplyFuture reply;
+		if (req instanceof ServiceRequestMessage){
+			reply = new ServiceReplyFutureImpl(10000, scopes);
+		} else if (req instanceof AttributeRequestMessage){
+			reply = new AttributeReplyFutureImpl(10000, scopes);
+		} else {
+			reply = new NonThreadedReplyFuture(10000, scopes);
+		}
+
+		threadPool.execute(new AsynchRequestThread(reply,req,scopes));
+
+		return reply;
+	}
+
+	/**
+	 * send a request to a DA.
+	 * 
+	 * @param req
+	 *            the request.
+	 * @param dAaddresses
+	 *            the DA address.
+	 * @return the <code>List</code> of results.
+	 * @throws ServiceLocationException
+	 */
+	private static void sendRequestToDA(final ReplyFuture replyfuture, final AbstractSLPRequestMessage req,
+			final List<String> dAaddresses, final String[] scopes) {
+	
+		threadPool.execute(new AsynchDAThread(replyfuture,req,dAaddresses, scopes));
+	}
+
+
+	/**
+	 * Thread responsible for sending a request to one or more DAs
+	 * 
+	 * @author breul
+	 *
+	 */
+	private static class AsynchDAThread implements Runnable {
+
+
+		// The reply future to be filled in
+		private final ReplyFuture replyfuture;
+
+		// The message to be sent
+		private final AbstractSLPRequestMessage msg;
+
+		// The DAs to be contacted
+		private final List<String> dAs;
+
+		// The scope this request is covering
+		private final String[] scopes;
+
+		/**
+		 * The constructor to kick off requests to DAs
+		 * 
+		 * @param rf
+		 * 			The reply future to be filled in
+		 * @param req
+		 * 			The message to be sent (a request)
+		 * @param dAaddresses
+		 * 			The List of DA addresses to be contacted
+		 */
+		public AsynchDAThread(ReplyFuture rf, AbstractSLPRequestMessage req, List<String> dAaddresses, String[] scopes){
+			replyfuture=rf;
+			msg=req;
+			dAs=dAaddresses;
+			this.scopes=scopes;
+
+		}
+
+
+		public void run() {
+			while (dAs.size()>0) {
+				int index = 0;
+				try {
+					// often there will be only one...
+					if (dAs.size()>1){
+						index = (int) Math.rint(Math.random()*(dAs.size()-1));
+					}
+					// set the receiver address
+					InetAddress address = InetAddress.getByName((String) dAs
+							.get(index));
+					int port = SLPCore.SLP_PORT;
+					AbstractSLPReplyMessage reply = SLPCore.sendReliableUnicastMessage(msg,new InetSocketAddress(address,port) ,true);
+					if (reply == null){
+						// remove DA from list.
+						final Object url = dAs.get(index);
+						SLPUtils.removeValueFromAll(SLPCore.dAs, url);
+						SLPCore.dASPIs.remove(url);
+						dAs.remove(index);
+						// Try the next DA in the list.
+						continue;
+					}
+					// add the reply to the future and mark the scope used as "handled"
+					replyfuture.add(reply);
+					break;
+
+				} catch (Exception e) {
+					SLPCore.platform.logError(e.getMessage(), e
+							.fillInStackTrace());
+					// something went wrong.
+					// remove DA from list.
+					final Object url = dAs.get(index);
+					SLPUtils.removeValueFromAll(SLPCore.dAs, url);
+					SLPCore.dASPIs.remove(url);
+					dAs.remove(index);
+					// Try the next DA in the list.
+					continue;
+				}
+			}
+			// mark the reply future as done unless there are still other scopes to be handled.
+			replyfuture.setDone(scopes,false);
+		}
+}
+
+
+
+
+	/**
+	 * The thread used to send requests, either to pass them on to DAs or two kick off a multicast convergence
+	 * 
+	 * @author breul
+	 *
+	 */
+	private static class AsynchRequestThread implements Runnable{
+
+		// The reply future to be filled in
+		private final ReplyFuture replyfuture;
+
+		// The message to be sent (a request)
+		private final AbstractSLPRequestMessage msg;
+
+		// The scopes to handle
+		private final List<String> scopes;
+
+
+
+		/**
+		 * The constructor to start the request
+		 * 
+		 * @param rf
+		 * 			The reply future to fill in
+		 * @param req
+		 * 			The request to send
+		 * @param scopelist
+		 * 			The list of scopes to be handled
+		 */
+		public AsynchRequestThread(ReplyFuture rf, AbstractSLPRequestMessage req, List<String> scopelist){
+			replyfuture=rf;
+			msg=req;
+			scopes=scopelist;
+		}
+
+		public void run(){
+			// if a UA is in multiple scopes, and a DA is also in these multiple scopes, then the UA
+			// would send the same request to such  DA for each scope. Therefor we keep track
+			// of DAs that have been contacted.
+			List<String> usedDAs = new ArrayList<String>();
+			boolean scopeOverlap = false;
+
+			for (String scope:scopes) {
+				scope = scope.toLowerCase();
+				List<String> dAs = SLPCore.dAs.get(scope);
+
+				SLPCore.platform
+				.logDebug("DAS FOR SCOPE " + scope + ": " + dAs);
+
+				// no DA for the scope known ?
+				// try to find one
+				if ((dAs == null || dAs.isEmpty()) && !SLPCore.noDiscovery) {
+					try {
+						SLPCore.daLookup(new String[] { scope });
+					} catch (ServiceLocationException sle){
+
+					}
+
+					// wait a short time for incoming replies
+					synchronized (SLPCore.dAs) {
+						try {
+							SLPCore.dAs.wait(SLPCore.CONFIG.getWaitTime() / 4);
+						} catch (InterruptedException e) {
+							SLPCore.platform.logError(e.getMessage(), e);
+							// Restore the interrupted status as we're not the owner of the current thread
+							Thread.currentThread().interrupt();
+						}
+					}
+					dAs = SLPCore.dAs.get(scope);
+
+				}
+				List<String> newDas = new ArrayList<String>();
+				// remove those already contacted while handling a previous scope...
+				if (dAs!=null){
+					for (String s: dAs){
+						if (usedDAs.contains(s)){
+							scopeOverlap = true;
+						} else {
+							newDas.add(s);
+						}
+					}
+				}
+
+				if (newDas != null && !newDas.isEmpty()) {
+					// a DA is known for this scope which has not already been asked in a different scope, so contact it
+					sendRequestToDA(replyfuture,msg,newDas, new String[]{scope});
+					// add DA to set of used DAs
+					usedDAs.addAll(newDas);
+					// reset overlap flag
+					scopeOverlap = false;
+				} else if (scopeOverlap){
+					// No new DA around for this scope, as the scope was covered by a previous request
+					replyfuture.setDone(new String[]{scope}, false);
+				} else {
+					// still no DA available and no overlap of scopes and DAs, use multicast
+					try {
+						// TODO: clarify scope handling in MCC
+						// two possibilities:
+						// a: include all scopes in mcc, leading to repeat responses from SAs and DAs in more than one scope, but we can break after only 1 MCC
+						// b: send to only a specific scope, possibly leading to multiple rounds of MCC
+						// c: add known responders to the initial mcc request to minimize traffic (as done now).
+						msg.setPrevResponders(replyfuture.getResponders());
+						SLPCore.multicastConvergence(replyfuture,msg);
+					} catch (ServiceLocationException sle){
+
+						continue;
+					}
+
+				}
+			}
+
+		}
+
+
+	}
+
+
+	/* (non-Javadoc)
+	 * @see ch.ethz.iks.slp.Locator#isUseAttributeListExtension()
+	 */
+	public boolean isUseAttributeListExtension() {
+		return useAttributeListExtension;
+	}
+
+	/* (non-Javadoc)
+	 * @see ch.ethz.iks.slp.Locator#setUseAttributeListExtension(boolean)
+	 */
+	public void setUseAttributeListExtension(boolean useAttributeListExtension) {
+		this.useAttributeListExtension = useAttributeListExtension;
+	}
+	
+	
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/LocatorImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,284 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.directory.slp.ReplyFuture;
+import org.apache.directory.slp.messages.AbstractSLPReplyMessage;
+
+/**
+ * The future returned when performing SLP lookups. It can be accessed while results still come in using next(),
+ * or after all results have arrived using getResult().
+ * 
+ * @author Lorenz Breu
+ */
+public class NonThreadedReplyFuture implements ReplyFuture{
+
+	// used to wait for done status
+	protected final Object donelock = new Object();
+	
+	//List of responses (i.e. message results)
+	protected final List<String> responses = new ArrayList<String>();
+	
+	// List of responders, used to build initial list of previous responders for multicast convergence
+	protected final List<String> responders = new ArrayList<String>();
+	
+	// point when reply future is closed automatically
+	protected long timeout;
+	
+	// set to true when all operations producing results have completed
+	protected boolean done = false;
+	
+	// the next position to be returned using the next() method.
+	// currently a future object is read by only one consumer.
+	private int nextPosition = 0;
+	
+	// the list of scopes this future has to cover, used to control correct closure.
+	private List<String> unhandledScopes = new ArrayList<String>();
+	
+	
+	
+	/**
+	 * Basic constructor, sets a default timeout value and uses all scopes definied in CONFIG
+	 */
+	public NonThreadedReplyFuture(){
+		//TODO: which wait time should we use here? has to be larger than the time it takes to start and end the multicast convergence
+		this(SLPCore.CONFIG.getWaitTime()*5);
+	}
+	
+	
+	
+	
+	/**
+	 * Constructor with a specific lifetime. The future expects to handle all scopes defined in CONFIG
+	 * 
+	 * @param lifetime
+	 * 				Number of milliseconds this future should remain open to receive results.
+	 */
+	public NonThreadedReplyFuture(long lifetime){
+		unhandledScopes = SLPUtils.stringToList(SLPCore.CONFIG.getScopes().toLowerCase(), ",");
+		timeout = System.currentTimeMillis()+lifetime;
+		
+	}
+	
+	
+	/**
+	 * Detailed constructor.
+	 * 
+	 * @param lifetime
+	 * 			Number of milliseconds this future should remain open to receive results.
+	 * @param scopes
+	 * 			List of scopes to be handled.
+	 */
+	public NonThreadedReplyFuture(long lifetime,List<String> scopes){
+		for (String s : scopes){
+			unhandledScopes.add(s.toLowerCase());
+		}
+		timeout = System.currentTimeMillis()+lifetime;
+		
+	}
+	
+	
+	
+	/**
+	 * Adds the result of an SLP reply message to the list of responses and the sender of the 
+	 * reply to the list of responders, if the error code is 0. 
+	 * 
+	 * @param reply
+	 * 			An AbstractSLPReplyMessage obtained through unicast or multicast
+	 */
+	public void add(AbstractSLPReplyMessage reply){
+
+		if (System.currentTimeMillis()>=timeout){
+			setDone(new String[]{}, true);
+			return;
+		}
+		
+		if (reply==null || reply.getErrorCode()!=0){
+			return;
+		}
+		if (done){
+			// this reply is coming in too late...
+			return;
+		}
+		
+		synchronized (responders){
+			if (!responders.contains(reply.getSource())) {
+				responders.add(reply.getSource());
+			} else {
+				return;
+			}
+		}
+		
+		synchronized(responses){
+			List<String> res = reply.getResultAsList();
+			if (res!=null && res.size()>0){
+				List<String> resp = reply.getResultAsList();
+				for (String s: resp){
+					if (!responses.contains(s)){
+						responses.add(s);
+					}
+				}
+				responses.notifyAll();
+			}
+		}
+		
+	}
+	
+	/**
+	 * Close the future.
+	 * If the override flag is set, the future will be closed directly.
+	 * If override is false, then the defined scopes will be removed from the list of unhandled scopes
+	 * and the future will be closed only if no scopes remain unhandled. Else it will remain open.
+	 * 
+	 * @param scopes
+	 * 			The scopes to mark as done.
+	 * @param override
+	 * 			Set to true if the future should be closed even if scopes remain unhandled (e.g. timeout)
+	 */
+	public synchronized void setDone(String[] scopes, boolean override){
+		synchronized (unhandledScopes){
+			for (String s: scopes){
+				unhandledScopes.remove(s);
+			}
+		}
+		
+		if (!unhandledScopes.isEmpty() && !override){
+			//oops, not all scopes that were expected to be handled actually were handled, so keep waiting
+			return;
+		}
+		if (!done){
+			done=true;
+			synchronized(donelock){
+				donelock.notifyAll();
+			}
+			synchronized(responses){
+				responses.notifyAll();
+			}
+			
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see ch.ethz.iks.slp.ServiceLocationEnumeration#next()
+	 */
+	public String next(){
+		// NOTE: a future is currently only read by one consumer (i.e. LocatorImpl) and therefor a single
+		// position marker is sufficient. Also the data containers holding responses must add new elements to the end.
+		synchronized(responses){
+			while (!done){
+				long remaining = timeout - System.currentTimeMillis();
+				if (remaining>0){
+					if (responses.size()>nextPosition){
+						return responses.get(nextPosition++);
+					}
+					try{
+						responses.wait(remaining);
+					} catch (InterruptedException e){
+						continue;
+					}
+				} else {
+					setDone(new String[]{}, true);
+					break;
+				}
+			}
+			if (responses.size()>nextPosition){
+				return responses.get(nextPosition++);
+			}
+			return null;
+		}
+	}
+	
+	
+	/**
+	 * Returns the status of the future.
+	 * 
+	 * @return
+	 * 		True if done, false if results can still be added.
+	 */
+	public synchronized boolean isDone(){
+		return done;
+	}
+	
+	
+	/**
+	 * Blocking call that waits until the future is marked as "done" before returning all available responses.
+	 * 
+	 * @return
+	 * 		A list of all results obtained during the unicast or multicast SLP operation in the form of Strings.
+	 */
+	public List<String> getResult(){
+		while (!done){
+			synchronized (donelock){
+				try {
+					long remaining = timeout - System.currentTimeMillis();
+					if (remaining>0){
+						donelock.wait(remaining);
+					} else {
+						setDone(new String[]{}, true);
+						break;
+					}
+				} catch (InterruptedException ie){
+					continue;
+				}
+			}
+		}
+		return responses;
+	}
+	
+	
+	/**
+	 * Returns the sources of all reply messages with error code 0 passed on to this future. 
+	 * 
+	 * @return
+	 * 		Array of IP addresses as Strings in dot notation of the sources of reply messages.
+	 */
+	public synchronized String[] getResponders(){
+		return SLPUtils.listToStringArray(responders);
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.util.Enumeration#hasMoreElements()
+	 */
+	public synchronized boolean hasMoreElements() {
+		return (responses.size()>nextPosition);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.util.Enumeration#nextElement()
+	 */
+	public String nextElement() {
+		return next();
+	}
+	
+	
+	
+	
+
+	
+	
+	
+	
+	
+	
+	
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/NonThreadedReplyFuture.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java
URL: http://svn.apache.org/viewvc/directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java?rev=782968&view=auto
==============================================================================
--- directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java (added)
+++ directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java Tue Jun  9 12:00:29 2009
@@ -0,0 +1,224 @@
+/* 
+ *   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.directory.slp.impl;
+
+import java.util.Dictionary;
+
+import org.apache.directory.slp.impl.filter.Filter;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+/**
+ * Platform abstraction for the OSGi implementation.
+ * 
+ * @author Jan S. Rellermeyer
+ */
+public class OSGiPlatformAbstraction implements PlatformAbstraction,
+		ServiceListener {
+
+	/**
+	 * 
+	 */
+	private final BundleContext context;
+
+	/**
+	 * 
+	 */
+	private LogService log = new NullPatternLogService();		
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param context
+	 *            the bundle context from the OSGi framework.
+	 * @param log
+	 *            the LogService, or null.
+	 * @param debug
+	 *            true if debugging is enabled.
+	 * @throws InvalidSyntaxException 
+	 * 				may never happen
+	 */
+	OSGiPlatformAbstraction(BundleContext context) throws InvalidSyntaxException {
+		this.context = context;
+
+		// initially get the LogService
+		final ServiceReference sref = context
+				.getServiceReference(LogService.class.getName());
+		if (sref != null) {
+			this.log = (LogService) context.getService(sref);
+		}
+
+		// track the LogService for life cycle events
+		context.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + LogService.class.getName() + ")");
+
+		logDebug("jSLP OSGi started.");
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#createFilter(java.lang.String)
+	 */
+	public Filter createFilter(String filterString) {
+		try {
+			final org.osgi.framework.Filter filter = context
+					.createFilter(filterString);
+			return new Filter() {
+				public boolean match(Dictionary values) {
+					return filter.match(values);
+				}
+
+				public String toString() {
+					return filter.toString();
+				}
+			};
+		} catch (InvalidSyntaxException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logDebug(java.lang.String)
+	 */
+	public void logDebug(String message) {
+		if(SLPCore.CONFIG.getDebugEnabled()) {
+			log.log(LogService.LOG_DEBUG, message);
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logDebug(java.lang.String,
+	 *      java.lang.Throwable)
+	 */
+	public void logDebug(String message, Throwable exception) {
+		if(SLPCore.CONFIG.getDebugEnabled()) {
+			log.log(LogService.LOG_DEBUG, message, exception);
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logError(java.lang.String)
+	 */
+	public void logError(String message) {
+		log.log(LogService.LOG_ERROR, message);
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logError(java.lang.String,
+	 *      java.lang.Throwable)
+	 */
+	public void logError(String message, Throwable exception) {
+		log.log(LogService.LOG_ERROR, message, exception);
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logTraceMessage(java.lang.String)
+	 */
+	public void logTraceMessage(String message) {
+		if(SLPCore.CONFIG.getTraceMessage()) {
+			log.log(LogService.LOG_INFO, message);
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logTraceDrop(java.lang.String)
+	 */
+	public void logTraceDrop(String message) {
+		if(SLPCore.CONFIG.getTraceDrop()) {
+			log.log(LogService.LOG_INFO, message);
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logTraceMessage(java.lang.String)
+	 */
+	public void logTraceReg(String message) {
+		if(SLPCore.CONFIG.getTraceReg()) {
+			log.log(LogService.LOG_INFO, message);
+		}
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logWarning(java.lang.String)
+	 */
+	public void logWarning(String message) {
+		log.log(LogService.LOG_WARNING, message);
+	}
+
+	/**
+	 * 
+	 * @see org.apache.directory.slp.impl.PlatformAbstraction#logWarning(java.lang.String,
+	 *      java.lang.Throwable)
+	 */
+	public void logWarning(String message, Throwable exception) {
+		log.log(LogService.LOG_WARNING, message, exception);
+	}
+
+	/**
+	 * 
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(final ServiceEvent event) {
+		switch (event.getType()) {
+		case ServiceEvent.REGISTERED:
+			log = (LogService) context.getService(event.getServiceReference());
+			return;
+		case ServiceEvent.UNREGISTERING:
+			log = new NullPatternLogService();
+		default:
+		}
+	}
+	
+	// if no LogService is present, we use a dummy log
+	private class NullPatternLogService implements LogService {
+
+		public void log(int level, String message) {
+			if(level == LogService.LOG_ERROR || level == LogService.LOG_WARNING) {
+				System.err.println(message);
+			} else {
+				System.out.println(message);
+			}
+		}
+
+		public void log(int level, String message, Throwable exception) {
+			log(level, message + exception.getMessage());
+		}
+
+		public void log(ServiceReference sr, int level, String message) {
+			log(null, level, message);
+		}
+
+		public void log(ServiceReference sr, int level, String message, Throwable t) {
+			log(null, level, message, t);
+		}
+	}
+}

Propchange: directory/sandbox/slp/src/main/java/org/apache/directory/slp/impl/OSGiPlatformAbstraction.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain