felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Peter Kriens <peter.kri...@aqute.biz>
Subject Re: Exception while using obr repository file generated by the bundleplugin
Date Wed, 04 Mar 2009 11:32:20 GMT
The filter is part of Bindex, which is already licensed under Apache  
code.

Kind regards,

	Peter Kriens


/*
  * Copyright (c) 2000 Gatespace AB. All Rights Reserved.
  * Copyright (c) OSGi Alliance (2002, 2006, 2007). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
package org.osgi.impl.bundle.obr.resource;

import java.lang.reflect.*;
import java.math.BigInteger;
import java.util.*;

public class FilterImpl {
	final char		WILDCARD	= 65535;

	final int		EQ			= 0;
	final int		LE			= 1;
	final int		GE			= 2;
	final int		APPROX		= 3;
	final int		LESS		= 4;
	final int		GREATER		= 5;
	final int		SUBSET		= 6;
	final int		SUPERSET	= 7;

	private String	filter;

	abstract class Query {
		static final String	GARBAGE		= "Trailing garbage";
		static final String	MALFORMED	= "Malformed query";
		static final String	EMPTY		= "Empty list";
		static final String	SUBEXPR		= "No subexpression";
		static final String	OPERATOR	= "Undefined operator";
		static final String	TRUNCATED	= "Truncated expression";
		static final String	EQUALITY	= "Only equality supported";

		private String		tail;

		boolean match() throws IllegalArgumentException {
			tail = filter;
			boolean val = doQuery();
			if (tail.length() > 0)
				error(GARBAGE);
			return val;
		}

		private boolean doQuery() throws IllegalArgumentException {
			if (tail.length() < 3 || !prefix("("))
				error(MALFORMED);
			boolean val;

			switch (tail.charAt(0)) {
				case '&' :
					val = doAnd();
					break;
				case '|' :
					val = doOr();
					break;
				case '!' :
					val = doNot();
					break;
				default :
					val = doSimple();
					break;
			}

			if (!prefix(")"))
				error(MALFORMED);
			return val;
		}

		private boolean doAnd() throws IllegalArgumentException {
			tail = tail.substring(1);
			boolean val = true;
			if (!tail.startsWith("("))
				error(EMPTY);
			do {
				if (!doQuery())
					val = false;
			} while (tail.startsWith("("));
			return val;
		}

		private boolean doOr() throws IllegalArgumentException {
			tail = tail.substring(1);
			boolean val = false;
			if (!tail.startsWith("("))
				error(EMPTY);
			do {
				if (doQuery())
					val = true;
			} while (tail.startsWith("("));
			return val;
		}

		private boolean doNot() throws IllegalArgumentException {
			tail = tail.substring(1);
			if (!tail.startsWith("("))
				error(SUBEXPR);
			return !doQuery();
		}

		private boolean doSimple() throws IllegalArgumentException {
			int op = 0;
			Object attr = getAttr();

			if (prefix("="))
				op = EQ;
			else if (prefix("<="))
				op = LE;
			else if (prefix(">="))
				op = GE;
			else if (prefix("~="))
				op = APPROX;
			else if (prefix("*>"))
				op = SUPERSET;
			else if (prefix("<*"))
				op = SUBSET;
			else if (prefix("<"))
				op = LESS;
			else if (prefix(">"))
				op = GREATER;
			else
				error(OPERATOR);

			return compare(attr, op, getValue());
		}

		private boolean prefix(String pre) {
			if (!tail.startsWith(pre))
				return false;
			tail = tail.substring(pre.length());
			return true;
		}

		private Object getAttr() {
			int len = tail.length();
			int ix = 0;
			label: for (; ix < len; ix++) {
				switch (tail.charAt(ix)) {
					case '(' :
					case ')' :
					case '<' :
					case '>' :
					case '=' :
					case '~' :
					case '*' :
					case '}' :
					case '{' :
					case '\\' :
						break label;
				}
			}
			String attr = tail.substring(0, ix).toLowerCase();
			tail = tail.substring(ix);
			return getProp(attr);
		}

		abstract Object getProp(String key);

		private String getValue() {
			StringBuffer sb = new StringBuffer();
			int len = tail.length();
			int ix = 0;
			label: for (; ix < len; ix++) {
				char c = tail.charAt(ix);
				switch (c) {
					case '(' :
					case ')' :
						break label;
					case '*' :
						sb.append(WILDCARD);
						break;
					case '\\' :
						if (ix == len - 1)
							break label;
						sb.append(tail.charAt(++ix));
						break;
					default :
						sb.append(c);
						break;
				}
			}
			tail = tail.substring(ix);
			return sb.toString();
		}

		private void error(String m) throws IllegalArgumentException {
			throw new IllegalArgumentException(m + " " + tail);
		}

		private boolean compare(Object obj, int op, String s) {
			if (obj == null) {
				// No value is ok for a subset
				if (op == SUBSET)
					return true;

				// No value is ok for a superset when the value is
				// empty
				if (op == SUPERSET) {
					return s.trim().length() == 0;
				}

				return false;
			}
			try {
				Class numClass = obj.getClass();
				if (numClass == String.class) {
					return compareString((String) obj, op, s);
				}
				else if (numClass == Character.class) {
					return compareString(obj.toString(), op, s);
				}
				else if (numClass == Long.class) {
					return compareSign(op, Long.valueOf(s)
							.compareTo((Long) obj));
				}
				else if (numClass == Integer.class) {
					return compareSign(op, Integer.valueOf(s).compareTo(
							(Integer) obj));
				}
				else if (numClass == Short.class) {
					return compareSign(op, Short.valueOf(s).compareTo(
							(Short) obj));
				}
				else if (numClass == Byte.class) {
					return compareSign(op, Byte.valueOf(s)
							.compareTo((Byte) obj));
				}
				else if (numClass == Double.class) {
					return compareSign(op, Double.valueOf(s).compareTo(
							(Double) obj));
				}
				else if (numClass == Float.class) {
					return compareSign(op, Float.valueOf(s).compareTo(
							(Float) obj));
				}
				else if (numClass == Boolean.class) {
					if (op != EQ)
						return false;
					int a = Boolean.valueOf(s).booleanValue() ? 1 : 0;
					int b = ((Boolean) obj).booleanValue() ? 1 : 0;
					return compareSign(op, a - b);
				}
				else if (numClass == BigInteger.class) {
					return compareSign(op, new BigInteger(s)
							.compareTo((BigInteger) obj));
				}
				else if (obj instanceof Collection) {
					if (op == SUBSET || op == SUPERSET) {
						StringSet set = new StringSet(s);
						if (op == SUBSET)
							return set.containsAll((Collection) obj);
						else
							return ((Collection) obj).containsAll(set);
					}

					for (Iterator i = ((Collection) obj).iterator(); i
							.hasNext();) {
						Object element = i.next();
						if (compare(element, op, s))
							return true;
					}
				}
				else if (numClass.isArray()) {
					int len = Array.getLength(obj);
					for (int i = 0; i < len; i++)
						if (compare(Array.get(obj, i), op, s))
							return true;
				}
				else {
					try {
						if (op == SUPERSET || op == SUBSET) {
							StringSet set = new StringSet(s);
							if (op == SUPERSET)
								return set.contains(obj);
							else
								return set.size() == 0
										|| (set.size() == 1 && set.iterator()
												.next().equals(obj));
						}
						else {
							Constructor constructor = numClass
									.getConstructor(new Class[] {String.class});
							Object instance = constructor
									.newInstance(new Object[] {s});
							switch (op) {
								case EQ :
									return obj.equals(instance);
								case LESS :
									return ((Comparable) obj)
											.compareTo(instance) < 0;
								case GREATER :
									return ((Comparable) obj)
											.compareTo(instance) > 0;
								case LE :
									return ((Comparable) obj)
											.compareTo(instance) <= 0;
								case GE :
									return ((Comparable) obj)
											.compareTo(instance) >= 0;
							}
						}
					}
					catch (Exception e) {
						e.printStackTrace();
						// Ignore
					}
				}
			}
			catch (Exception e) {
			}
			return false;
		}
	}

	class DictQuery extends Query {
		private Map	dict;

		DictQuery(Map dict) {
			this.dict = dict;
		}

		Object getProp(String key) {
			return dict.get(key);
		}
	}

	public FilterImpl(String filter) throws IllegalArgumentException {
		// NYI: Normalize the filter string?
		this.filter = filter;
		if (filter == null || filter.length() == 0)
			throw new IllegalArgumentException("Null query");
	}

	public boolean match(Map dict) {
		try {
			return new DictQuery(dict).match();
		}
		catch (IllegalArgumentException e) {
			return false;
		}
	}

	public String toString() {
		return filter;
	}

	public boolean equals(Object obj) {
		return obj != null && obj instanceof FilterImpl
				&& filter.equals(((FilterImpl) obj).filter);
	}

	public int hashCode() {
		return filter.hashCode();
	}

	boolean compareString(String s1, int op, String s2) {
		switch (op) {
			case EQ :
				return patSubstr(s1, s2);
			case APPROX :
				return patSubstr(fixupString(s1), fixupString(s2));
			default :
				return compareSign(op, s2.compareTo(s1));
		}
	}

	boolean compareSign(int op, int cmp) {
		switch (op) {
			case LE :
				return cmp >= 0;
			case GE :
				return cmp <= 0;
			case EQ :
				return cmp == 0;
			default : /* APPROX */
				return cmp == 0;
		}
	}

	String fixupString(String s) {
		StringBuffer sb = new StringBuffer();
		int len = s.length();
		boolean isStart = true;
		boolean isWhite = false;
		for (int i = 0; i < len; i++) {
			char c = s.charAt(i);
			if (Character.isWhitespace(c)) {
				isWhite = true;
			}
			else {
				if (!isStart && isWhite)
					sb.append(' ');
				if (Character.isUpperCase(c))
					c = Character.toLowerCase(c);
				sb.append(c);
				isStart = false;
				isWhite = false;
			}
		}
		return sb.toString();
	}

	boolean patSubstr(String s, String pat) {
		if (s == null)
			return false;
		if (pat.length() == 0)
			return s.length() == 0;
		if (pat.charAt(0) == WILDCARD) {
			pat = pat.substring(1);
			for (;;) {
				if (patSubstr(s, pat))
					return true;
				if (s.length() == 0)
					return false;
				s = s.substring(1);
			}
		}
		else {
			if (s.length() == 0 || s.charAt(0) != pat.charAt(0))
				return false;
			return patSubstr(s.substring(1), pat.substring(1));
		}
	}
}


On 4 mrt 2009, at 07:18, Kristian Köhler wrote:

> Hi
>
> if you send me the filter I could try to build the patch...
>
> Kristian
>
> 2009/3/3 Peter Kriens <peter.kriens@aqute.biz>
>
>> Hmm, it often feels more like committeD ...
>>
>> Kind regards,
>>
>>       Peter Kriens
>>
>>
>> On 3 mrt 2009, at 17:04, Richard S. Hall wrote:
>>
>> You are a committer. :-)
>>>
>>> -> richard
>>>
>>> Peter Kriens wrote:
>>>
>>>> Implement these operators? I can send you the source code for a  
>>>> filter
>>>> that implements them ...
>>>>
>>>> Kind regards,
>>>>
>>>>  Peter Kriens
>>>>
>>>> On 3 mrt 2009, at 16:11, Richard S. Hall wrote:
>>>>
>>>> The issue is that bindex (which generates the repository.xml  
>>>> file) is
>>>>> using non-standard LDAP operators which are not supported by the  
>>>>> OBR
>>>>> implementation. In this case, the "mandatory" directive on your  
>>>>> bundle is
>>>>> resulting in a subset operator, I believe, which is not standard  
>>>>> LDAP.
>>>>>
>>>>> This is a known issue, although we have no solution for it at  
>>>>> present.
>>>>>
>>>>> -> richard
>>>>>
>>>>> Kristian Köhler wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> I'm trying to add/install some local jar files to my local OBR
>>>>>> repository
>>>>>> and then use these jar-files within felix via the bundle  
>>>>>> repository.
>>>>>> For
>>>>>> most of the files this seems to work fine but some files are  
>>>>>> corrupting
>>>>>> my
>>>>>> repository (file). The following 'require' element is generated 

>>>>>> within
>>>>>> the
>>>>>> obr repository file for the spring-core-2.5.6.jar file for  
>>>>>> example:
>>>>>>
>>>>>> --- 8< ---
>>>>>>
>>>>>> <require extend="false"
>>>>>>
>>>>>> filter="(&amp;(package=org.eclipse.core.runtime) 
>>>>>> (version&gt;=0.0.0)(common=split)(mandatory:&lt;*common))"
>>>>>> multiple="false" name="package" optional="true">Import package
>>>>>> org.eclipse.core.runtime</require>
>>>>>>
>>>>>> --- 8< ---
>>>>>>
>>>>>> This elements causes the parser to throw the following  
>>>>>> exception when
>>>>>> invoking 'obr list' via the felix shell:
>>>>>>
>>>>>> --- 8< ---
>>>>>>
>>>>>> ERROR: Error parsing repository metadata
>>>>>> org.osgi.framework.InvalidSyntaxException: expected ~=|>=|<=
>>>>>> at org.apache.felix.framework.FilterImpl.<init>(FilterImpl.java:

>>>>>> 81)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .framework 
>>>>>> .BundleContextImpl.createFilter(BundleContextImpl.java:102)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RequirementImpl.setFilter(RequirementImpl.java:57)
>>>>>> at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
>>>>>> at
>>>>>>
>>>>>> sun 
>>>>>> .reflect 
>>>>>> .DelegatingMethodAccessorImpl 
>>>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .metadataparser 
>>>>>> .XmlCommonHandler.startElement(XmlCommonHandler.java:490)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .metadataparser 
>>>>>> .kxmlsax.KXml2SAXParser.parseXML(KXml2SAXParser.java:67)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RepositoryImpl.parseRepositoryFile(RepositoryImpl.java:256)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.bundlerepository.RepositoryImpl.access 
>>>>>> $000(RepositoryImpl.java:44)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.bundlerepository.RepositoryImpl 
>>>>>> $1.run(RepositoryImpl.java:75)
>>>>>> at java.security.AccessController.doPrivileged(Native Method)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository.RepositoryImpl.<init>(RepositoryImpl.java:71)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository.RepositoryImpl.<init>(RepositoryImpl.java:60)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RepositoryAdminImpl.initialize(RepositoryAdminImpl.java:206)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RepositoryAdminImpl.discoverResources(RepositoryAdminImpl.java:

>>>>>> 126)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix.bundlerepository.ObrCommandImpl.list(ObrCommandImpl.java:

>>>>>> 210)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository.ObrCommandImpl.execute(ObrCommandImpl.java:104)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.shell.impl.Activator 
>>>>>> $ShellServiceImpl.executeCommand(Activator.java:276)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.shell.tui.Activator 
>>>>>> $ShellTuiRunnable.run(Activator.java:167)
>>>>>> at java.lang.Thread.run(Thread.java:619)
>>>>>> WARNING: RepositoryAdminImpl: Exception creating repository
>>>>>> file:/home/kkoehler/repository.xml. Repository is skipped.
>>>>>> java.lang.reflect.InvocationTargetException
>>>>>> at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
>>>>>> at
>>>>>>
>>>>>> sun 
>>>>>> .reflect 
>>>>>> .DelegatingMethodAccessorImpl 
>>>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .metadataparser 
>>>>>> .XmlCommonHandler.startElement(XmlCommonHandler.java:490)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .metadataparser 
>>>>>> .kxmlsax.KXml2SAXParser.parseXML(KXml2SAXParser.java:67)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RepositoryImpl.parseRepositoryFile(RepositoryImpl.java:256)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.bundlerepository.RepositoryImpl.access 
>>>>>> $000(RepositoryImpl.java:44)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.bundlerepository.RepositoryImpl 
>>>>>> $1.run(RepositoryImpl.java:75)
>>>>>> at java.security.AccessController.doPrivileged(Native Method)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository.RepositoryImpl.<init>(RepositoryImpl.java:71)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository.RepositoryImpl.<init>(RepositoryImpl.java:60)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RepositoryAdminImpl.initialize(RepositoryAdminImpl.java:206)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RepositoryAdminImpl.discoverResources(RepositoryAdminImpl.java:

>>>>>> 126)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix.bundlerepository.ObrCommandImpl.list(ObrCommandImpl.java:

>>>>>> 210)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository.ObrCommandImpl.execute(ObrCommandImpl.java:104)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.shell.impl.Activator 
>>>>>> $ShellServiceImpl.executeCommand(Activator.java:276)
>>>>>> at
>>>>>>
>>>>>> org.apache.felix.shell.tui.Activator 
>>>>>> $ShellTuiRunnable.run(Activator.java:167)
>>>>>> at java.lang.Thread.run(Thread.java:619)
>>>>>> Caused by: org.osgi.framework.InvalidSyntaxException: expected  
>>>>>> ~=|>=|<=
>>>>>> at org.apache.felix.framework.FilterImpl.<init>(FilterImpl.java:

>>>>>> 81)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .framework 
>>>>>> .BundleContextImpl.createFilter(BundleContextImpl.java:102)
>>>>>> at
>>>>>>
>>>>>> org 
>>>>>> .apache 
>>>>>> .felix 
>>>>>> .bundlerepository 
>>>>>> .RequirementImpl.setFilter(RequirementImpl.java:57)
>>>>>> ... 18 more
>>>>>>
>>>>>> --- 8< ---
>>>>>>
>>>>>> The parser expects "~=|>=|<=" but found "mandatory:<*common"
>>>>>> ('explicit'
>>>>>> generated by the org.osgi.impl.bundle.obr.resource.BundleInfo  
>>>>>> class).
>>>>>>
>>>>>> So I'm not sure what's going wrong here ;-) and how to fix this.
>>>>>> Is this the wrong syntax or is it a parser problem?
>>>>>>
>>>>>> I'm using trunk versions of the bundle repository and the  
>>>>>> bundleplugin
>>>>>> by
>>>>>> the way...
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>> Kristian
>>>>>>
>>>>>>
>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>
>>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>
>
> -- 
> http://www.kkoehler.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Mime
View raw message