pax_global_header00006660000000000000000000000064115566034260014522gustar00rootroot0000000000000052 comment=6dce1664534cb1f44a75337cc37bea8e7e96a97b felix-utils-1.1.0/000077500000000000000000000000001155660342600137665ustar00rootroot00000000000000felix-utils-1.1.0/DEPENDENCIES000066400000000000000000000014251155660342600155410ustar00rootroot00000000000000Apache Felix Utils Copyright 2010 The Apache Software Foundation This software was developed at the Apache Software Foundation (http://www.apache.org) and may have dependencies on other Apache software licensed under Apache License 2.0. I. Included Third-Party Software This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License 2.0. II. Used Third-Party Software This product uses software developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License 2.0. This product uses software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2010). Licensed under the Apache License 2.0. III. License Summary - Apache License 2.0 felix-utils-1.1.0/LICENSE000066400000000000000000000261361155660342600150030ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. felix-utils-1.1.0/NOTICE000066400000000000000000000003161155660342600146720ustar00rootroot00000000000000Apache Felix Utils Copyright 2010 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License 2.0. felix-utils-1.1.0/doc/000077500000000000000000000000001155660342600145335ustar00rootroot00000000000000felix-utils-1.1.0/doc/changelog.txt000066400000000000000000000007041155660342600172240ustar00rootroot00000000000000Changes 1.0.0 to 1.1.0 ---------------------- ** New Feature * New org.apache.felix.utils.collections.DictionaryAsMap class to wrap a Dictionary as a Map * New org.apache.felix.utils.properties.InterpolationHelper to interpolate a Map of properties using ${xx} replacements * New org.apache.felix.utils.properties.Properties class to load/save properties and allow editing them without loosing the user formatting felix-utils-1.1.0/pom.xml000066400000000000000000000053361155660342600153120ustar00rootroot00000000000000 org.apache.felix felix-parent 1.2.1 4.0.0 Apache Felix Utils Utility classes for OSGi. 1.1.0 org.apache.felix.utils org.osgi org.osgi.core 4.1.0 org.osgi org.osgi.compendium 4.1.0 maven-compiler-plugin 1.5 jsr14 org.codehaus.mojo rat-maven-plugin false true true doc/* maven-eclipse.xml .checkstyle .externalToolBuilders/* scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.utils-1.1.0 scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.utils-1.1.0 scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.utils-1.1.0 felix-utils-1.1.0/src/000077500000000000000000000000001155660342600145555ustar00rootroot00000000000000felix-utils-1.1.0/src/main/000077500000000000000000000000001155660342600155015ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/000077500000000000000000000000001155660342600164225ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/000077500000000000000000000000001155660342600172115ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/000077500000000000000000000000001155660342600204325ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/000077500000000000000000000000001155660342600215415ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/000077500000000000000000000000001155660342600227015ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/collections/000077500000000000000000000000001155660342600252175ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/collections/DictionaryAsMap.java000066400000000000000000000055511155660342600311170ustar00rootroot00000000000000/* * 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.felix.utils.collections; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Dictionary; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * A wrapper around a dictionary access it as a Map */ public class DictionaryAsMap extends AbstractMap { private Dictionary dict; public DictionaryAsMap(Dictionary dict) { this.dict = dict; } @Override public Set> entrySet() { return new AbstractSet>() { @Override public Iterator> iterator() { final Enumeration e = dict.keys(); return new Iterator>() { private U key; public boolean hasNext() { return e.hasMoreElements(); } public Entry next() { key = e.nextElement(); return new KeyEntry(key); } public void remove() { if (key == null) { throw new IllegalStateException(); } dict.remove(key); } }; } @Override public int size() { return dict.size(); } }; } @Override public V put(U key, V value) { return dict.put(key, value); } class KeyEntry implements Map.Entry { private final U key; KeyEntry(U key) { this.key = key; } public U getKey() { return key; } public V getValue() { return dict.get(key); } public V setValue(V value) { return DictionaryAsMap.this.put(key, value); } } }felix-utils-1.1.0/src/main/java/org/apache/felix/utils/collections/IteratorToEnumeration.java000066400000000000000000000025561155660342600323750ustar00rootroot00000000000000/* * 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.felix.utils.collections; import java.util.Enumeration; import java.util.Iterator; public class IteratorToEnumeration implements Enumeration { private final Iterator iter; public IteratorToEnumeration(Iterator iter) { this.iter = iter; } public boolean hasMoreElements() { if (iter == null) { return false; } return iter.hasNext(); } public Object nextElement() { if (iter == null) { return null; } return iter.next(); } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/collections/MapToDictionary.java000066400000000000000000000043351155660342600311350ustar00rootroot00000000000000/* * 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.felix.utils.collections; import java.util.*; /** * This is a simple class that implements a Dictionary * from a Map. The resulting dictionary is immutatable. **/ public class MapToDictionary extends Dictionary { /** * Map source. **/ private Map map = null; public MapToDictionary(Map map) { this.map = map; } public void setSourceMap(Map map) { this.map = map; } public Enumeration elements() { if (map == null) { return null; } return new IteratorToEnumeration(map.values().iterator()); } public Object get(Object key) { if (map == null) { return null; } return map.get(key); } public boolean isEmpty() { if (map == null) { return true; } return map.isEmpty(); } public Enumeration keys() { if (map == null) { return null; } return new IteratorToEnumeration(map.keySet().iterator()); } public Object put(Object key, Object value) { throw new UnsupportedOperationException(); } public Object remove(Object key) { throw new UnsupportedOperationException(); } public int size() { if (map == null) { return 0; } return map.size(); } }felix-utils-1.1.0/src/main/java/org/apache/felix/utils/filter/000077500000000000000000000000001155660342600241665ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/filter/FilterImpl.java000066400000000000000000001446231155660342600271120ustar00rootroot00000000000000/* * 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.felix.utils.filter; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.*; import org.apache.felix.utils.version.VersionTable; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.framework.Version; /** * This filter implementation is based on the official OSGi filter with additional * support for the SUPERSET (>*) and SUBSET (<*) operators. * This filter also has a few optimizations (cached transformation). */ public class FilterImpl implements Filter { /* filter operators */ private static final int EQUAL = 1; private static final int APPROX = 2; private static final int GREATER = 3; private static final int LESS = 4; private static final int PRESENT = 5; private static final int SUBSTRING = 6; private static final int AND = 7; private static final int OR = 8; private static final int NOT = 9; private static final int SUBSET = 10; private static final int SUPERSET = 11; /** filter operation */ private final int op; /** filter attribute or null if operation AND, OR or NOT */ private final String attr; /** filter operands */ private final Object value; /** optim in case of version */ private final Object converted; /* normalized filter string for Filter object */ private transient volatile String filterString; /** * Constructs a {@link FilterImpl} object. This filter object may be * used to match a {@link org.osgi.framework.ServiceReference} or a Dictionary. * *

* If the filter cannot be parsed, an {@link org.osgi.framework.InvalidSyntaxException} * will be thrown with a human readable message where the filter became * unparsable. * * @param filterString the filter string. * @exception InvalidSyntaxException If the filter parameter contains an * invalid filter string that cannot be parsed. */ public static FilterImpl newInstance(String filterString) throws InvalidSyntaxException { return newInstance(filterString, false); } public static FilterImpl newInstance(String filterString, boolean ignoreCase) throws InvalidSyntaxException { return new Parser(filterString, ignoreCase).parse(); } FilterImpl(int operation, String attr, Object value) { this.op = operation; this.attr = attr; this.value = value; Object conv = null; try { if (op == SUBSET || op == SUPERSET) { conv = getSet(value); } else if ("version".equalsIgnoreCase(attr)) { if (value instanceof String) { conv = VersionTable.getVersion((String) value); } else if (value instanceof Version) { conv = (Version) value; } } } catch (Throwable t) { // Ignore any conversion issue } converted = conv; } /** * Filter using a service's properties. *

* This Filter is executed using the keys and values of the * referenced service's properties. The keys are case insensitively * matched with this Filter. * * @param reference The reference to the service whose properties are * used in the match. * @return true if the service's properties match this * Filter; false otherwise. */ public boolean match(ServiceReference reference) { return match0(new ServiceReferenceDictionary(reference)); } /** * Filter using a Dictionary. This Filter is * executed using the specified Dictionary's keys and * values. The keys are case insensitively matched with this * Filter. * * @param dictionary The Dictionary whose keys are used in * the match. * @return true if the Dictionary's keys and * values match this filter; false otherwise. * @throws IllegalArgumentException If dictionary contains * case variants of the same key name. */ public boolean match(Dictionary dictionary) { return match0(new CaseInsensitiveDictionary(dictionary)); } /** * Filter with case sensitivity using a Dictionary. This * Filter is executed using the specified * Dictionary's keys and values. The keys are case * sensitively matched with this Filter. * * @param dictionary The Dictionary whose keys are used in * the match. * @return true if the Dictionary's keys and * values match this filter; false otherwise. * @since 1.3 */ public boolean matchCase(Dictionary dictionary) { return match0(dictionary); } /** * Filter using a Map. This Filter is * executed using the specified Map's keys and * values. The keys are case insensitively matched with this * Filter. * * @param map The Map whose keys are used in * the match. * @return true if the Map's keys and * values match this filter; false otherwise. * @throws IllegalArgumentException If map contains * case variants of the same key name. */ public boolean matchCase(Map map) { return match0(map); } /** * Returns this Filter's filter string. *

* The filter string is normalized by removing whitespace which does not * affect the meaning of the filter. * * @return This Filter's filter string. */ public String toString() { String result = filterString; if (result == null) { filterString = result = normalize(); } return result; } /** * Returns this Filter's normalized filter string. *

* The filter string is normalized by removing whitespace which does not * affect the meaning of the filter. * * @return This Filter's filter string. */ private String normalize() { StringBuffer sb = new StringBuffer(); sb.append('('); switch (op) { case AND : { sb.append('&'); FilterImpl[] filters = (FilterImpl[]) value; for (int i = 0, size = filters.length; i < size; i++) { sb.append(filters[i].normalize()); } break; } case OR : { sb.append('|'); FilterImpl[] filters = (FilterImpl[]) value; for (int i = 0, size = filters.length; i < size; i++) { sb.append(filters[i].normalize()); } break; } case NOT : { sb.append('!'); FilterImpl filter = (FilterImpl) value; sb.append(filter.normalize()); break; } case SUBSTRING : { sb.append(attr); sb.append('='); String[] substrings = (String[]) value; for (int i = 0, size = substrings.length; i < size; i++) { String substr = substrings[i]; if (substr == null) /* * */{ sb.append('*'); } else /* xxx */{ sb.append(encodeValue(substr)); } } break; } case EQUAL : { sb.append(attr); sb.append('='); sb.append(encodeValue((String) value)); break; } case GREATER: { sb.append(attr); sb.append(">="); sb.append(encodeValue((String) value)); break; } case LESS: { sb.append(attr); sb.append("<="); sb.append(encodeValue((String) value)); break; } case APPROX : { sb.append(attr); sb.append("~="); sb.append(encodeValue(approxString((String) value))); break; } case PRESENT : { sb.append(attr); sb.append("=*"); break; } case SUBSET : { sb.append(attr); sb.append("<*"); sb.append(encodeValue(approxString((String) value))); break; } case SUPERSET : { sb.append(attr); sb.append("*>"); sb.append(encodeValue(approxString((String) value))); break; } } sb.append(')'); return sb.toString(); } /** * Compares this Filter to another Filter. * *

* This implementation returns the result of calling * this.toString().equals(obj.toString(). * * @param obj The object to compare against this Filter. * @return If the other object is a Filter object, then * returns the result of calling * this.toString().equals(obj.toString(); * false otherwise. */ public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof FilterImpl)) { return false; } return this.toString().equals(obj.toString()); } /** * Returns the hashCode for this Filter. * *

* This implementation returns the result of calling * this.toString().hashCode(). * * @return The hashCode of this Filter. */ public int hashCode() { return this.toString().hashCode(); } /** * Internal match routine. Dictionary parameter must support * case-insensitive get. * * @param properties A dictionary whose keys are used in the match. * @return If the Dictionary's keys match the filter, return * true. Otherwise, return false. */ private boolean match0(Dictionary properties) { switch (op) { case AND : { FilterImpl[] filters = (FilterImpl[]) value; for (int i = 0, size = filters.length; i < size; i++) { if (!filters[i].match0(properties)) { return false; } } return true; } case OR : { FilterImpl[] filters = (FilterImpl[]) value; for (int i = 0, size = filters.length; i < size; i++) { if (filters[i].match0(properties)) { return true; } } return false; } case NOT : { FilterImpl filter = (FilterImpl) value; return !filter.match0(properties); } case SUBSTRING : case EQUAL : case GREATER: case LESS: case APPROX : case SUBSET : case SUPERSET : { Object prop = (properties == null) ? null : properties .get(attr); return compare(op, prop, value); } case PRESENT : { Object prop = (properties == null) ? null : properties .get(attr); return prop != null; } } return false; } private boolean match0(Map properties) { switch (op) { case AND : { FilterImpl[] filters = (FilterImpl[]) value; for (int i = 0, size = filters.length; i < size; i++) { if (!filters[i].match0(properties)) { return false; } } return true; } case OR : { FilterImpl[] filters = (FilterImpl[]) value; for (int i = 0, size = filters.length; i < size; i++) { if (filters[i].match0(properties)) { return true; } } return false; } case NOT : { FilterImpl filter = (FilterImpl) value; return !filter.match0(properties); } case SUBSTRING : case EQUAL : case GREATER: case LESS: case APPROX : case SUBSET : case SUPERSET : { Object prop = (properties == null) ? null : properties .get(attr); return compare(op, prop, value); } case PRESENT : { Object prop = (properties == null) ? null : properties .get(attr); return prop != null; } } return false; } /** * Encode the value string such that '(', '*', ')' and '\' are escaped. * * @param value unencoded value string. * @return encoded value string. */ private static String encodeValue(String value) { boolean encoded = false; int inlen = value.length(); int outlen = inlen << 1; /* inlen 2 */ char[] output = new char[outlen]; value.getChars(0, inlen, output, inlen); int cursor = 0; for (int i = inlen; i < outlen; i++) { char c = output[i]; switch (c) { case '(' : case '*' : case ')' : case '\\' : { output[cursor] = '\\'; cursor++; encoded = true; break; } } output[cursor] = c; cursor++; } return encoded ? new String(output, 0, cursor) : value; } private Collection getSet(Object value) { Collection s; if (value instanceof Set) { s = (Set) value; } else if (value instanceof Collection) { s = (Collection) value; if (s.size() > 1) { s = new HashSet(s); } } else if (value != null) { String v = value.toString(); if (v.indexOf(',') < 0) { s = Collections.singleton(v); } else { StringTokenizer st = new StringTokenizer(value.toString(), ","); s = new HashSet(); while (st.hasMoreTokens()) { s.add(st.nextToken().trim()); } } } else { s = Collections.emptySet(); } return s; } private boolean compare(int operation, Object value1, Object value2) { if (op == SUPERSET || op == SUBSET) { Collection s1 = getSet(value1); Collection s2 = converted instanceof Collection ? (Collection) converted : getSet(value2); if (op == SUPERSET) { return s1.containsAll(s2); } else { return s2.containsAll(s1); } } if (value1 == null) { return false; } if (value1 instanceof String) { return compare_String(operation, (String) value1, value2); } Class clazz = value1.getClass(); if (clazz.isArray()) { Class type = clazz.getComponentType(); if (type.isPrimitive()) { return compare_PrimitiveArray(operation, type, value1, value2); } return compare_ObjectArray(operation, (Object[]) value1, value2); } if (value1 instanceof Version) { if (converted != null) { switch (operation) { case APPROX : case EQUAL : { return ((Version) value1).compareTo(converted) == 0; } case GREATER: { return ((Version) value1).compareTo(converted) >= 0; } case LESS: { return ((Version) value1).compareTo(converted) <= 0; } } } else { return compare_Comparable(operation, (Version) value1, value2); } } if (value1 instanceof Collection) { return compare_Collection(operation, (Collection) value1, value2); } if (value1 instanceof Integer) { return compare_Integer(operation, ((Integer) value1).intValue(), value2); } if (value1 instanceof Long) { return compare_Long(operation, ((Long) value1).longValue(), value2); } if (value1 instanceof Byte) { return compare_Byte(operation, ((Byte) value1).byteValue(), value2); } if (value1 instanceof Short) { return compare_Short(operation, ((Short) value1).shortValue(), value2); } if (value1 instanceof Character) { return compare_Character(operation, ((Character) value1) .charValue(), value2); } if (value1 instanceof Float) { return compare_Float(operation, ((Float) value1).floatValue(), value2); } if (value1 instanceof Double) { return compare_Double(operation, ((Double) value1) .doubleValue(), value2); } if (value1 instanceof Boolean) { return compare_Boolean(operation, ((Boolean) value1) .booleanValue(), value2); } if (value1 instanceof Comparable) { return compare_Comparable(operation, (Comparable) value1, value2); } return compare_Unknown(operation, value1, value2); // RFC 59 } private boolean compare_Collection(int operation, Collection collection, Object value2) { if (op == SUBSET || op == SUPERSET) { Set set = new HashSet(); if (value2 != null) { StringTokenizer st = new StringTokenizer(value2.toString(), ","); while (st.hasMoreTokens()) { set.add(st.nextToken().trim()); } } if (op == SUBSET) { return set.containsAll(collection); } else { return collection.containsAll(set); } } for (Iterator iterator = collection.iterator(); iterator.hasNext();) { if (compare(operation, iterator.next(), value2)) { return true; } } return false; } private boolean compare_ObjectArray(int operation, Object[] array, Object value2) { for (int i = 0, size = array.length; i < size; i++) { if (compare(operation, array[i], value2)) { return true; } } return false; } private boolean compare_PrimitiveArray(int operation, Class type, Object primarray, Object value2) { if (Integer.TYPE.isAssignableFrom(type)) { int[] array = (int[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Integer(operation, array[i], value2)) { return true; } } return false; } if (Long.TYPE.isAssignableFrom(type)) { long[] array = (long[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Long(operation, array[i], value2)) { return true; } } return false; } if (Byte.TYPE.isAssignableFrom(type)) { byte[] array = (byte[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Byte(operation, array[i], value2)) { return true; } } return false; } if (Short.TYPE.isAssignableFrom(type)) { short[] array = (short[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Short(operation, array[i], value2)) { return true; } } return false; } if (Character.TYPE.isAssignableFrom(type)) { char[] array = (char[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Character(operation, array[i], value2)) { return true; } } return false; } if (Float.TYPE.isAssignableFrom(type)) { float[] array = (float[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Float(operation, array[i], value2)) { return true; } } return false; } if (Double.TYPE.isAssignableFrom(type)) { double[] array = (double[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Double(operation, array[i], value2)) { return true; } } return false; } if (Boolean.TYPE.isAssignableFrom(type)) { boolean[] array = (boolean[]) primarray; for (int i = 0, size = array.length; i < size; i++) { if (compare_Boolean(operation, array[i], value2)) { return true; } } return false; } return false; } private boolean compare_String(int operation, String string, Object value2) { switch (operation) { case SUBSTRING : { String[] substrings = (String[]) value2; int pos = 0; for (int i = 0, size = substrings.length; i < size; i++) { String substr = substrings[i]; if (i + 1 < size) /* if this is not that last substr */{ if (substr == null) /* * */{ String substr2 = substrings[i + 1]; if (substr2 == null) /* ** */ continue; /* ignore first star */ /* xxx */ int index = string.indexOf(substr2, pos); if (index == -1) { return false; } pos = index + substr2.length(); if (i + 2 < size) // if there are more // substrings, increment // over the string we just // matched; otherwise need // to do the last substr // check i++; } else /* xxx */{ int len = substr.length(); if (string.regionMatches(pos, substr, 0, len)) { pos += len; } else { return false; } } } else /* last substr */{ if (substr == null) /* * */{ return true; } /* xxx */ return string.endsWith(substr); } } return true; } case EQUAL : { return string.equals(value2); } case APPROX : { string = approxString(string); String string2 = approxString((String) value2); return string.equalsIgnoreCase(string2); } case GREATER: { return string.compareTo((String) value2) >= 0; } case LESS: { return string.compareTo((String) value2) <= 0; } } return false; } private boolean compare_Integer(int operation, int intval, Object value2) { if (operation == SUBSTRING) { return false; } int intval2; try { intval2 = Integer.parseInt(((String) value2).trim()); } catch (IllegalArgumentException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return intval == intval2; } case GREATER: { return intval >= intval2; } case LESS: { return intval <= intval2; } } return false; } private boolean compare_Long(int operation, long longval, Object value2) { if (operation == SUBSTRING) { return false; } long longval2; try { longval2 = Long.parseLong(((String) value2).trim()); } catch (IllegalArgumentException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return longval == longval2; } case GREATER: { return longval >= longval2; } case LESS: { return longval <= longval2; } } return false; } private boolean compare_Byte(int operation, byte byteval, Object value2) { if (operation == SUBSTRING) { return false; } byte byteval2; try { byteval2 = Byte.parseByte(((String) value2).trim()); } catch (IllegalArgumentException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return byteval == byteval2; } case GREATER: { return byteval >= byteval2; } case LESS: { return byteval <= byteval2; } } return false; } private boolean compare_Short(int operation, short shortval, Object value2) { if (operation == SUBSTRING) { return false; } short shortval2; try { shortval2 = Short.parseShort(((String) value2).trim()); } catch (IllegalArgumentException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return shortval == shortval2; } case GREATER: { return shortval >= shortval2; } case LESS: { return shortval <= shortval2; } } return false; } private boolean compare_Character(int operation, char charval, Object value2) { if (operation == SUBSTRING) { return false; } char charval2; try { charval2 = ((String) value2).charAt(0); } catch (IndexOutOfBoundsException e) { return false; } switch (operation) { case EQUAL : { return charval == charval2; } case APPROX : { return (charval == charval2) || (Character.toUpperCase(charval) == Character .toUpperCase(charval2)) || (Character.toLowerCase(charval) == Character .toLowerCase(charval2)); } case GREATER: { return charval >= charval2; } case LESS: { return charval <= charval2; } } return false; } private boolean compare_Boolean(int operation, boolean boolval, Object value2) { if (operation == SUBSTRING) { return false; } boolean boolval2 = Boolean.valueOf(((String) value2).trim()) .booleanValue(); switch (operation) { case APPROX : case EQUAL : case GREATER: case LESS: { return boolval == boolval2; } } return false; } private boolean compare_Float(int operation, float floatval, Object value2) { if (operation == SUBSTRING) { return false; } float floatval2; try { floatval2 = Float.parseFloat(((String) value2).trim()); } catch (IllegalArgumentException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return Float.compare(floatval, floatval2) == 0; } case GREATER: { return Float.compare(floatval, floatval2) >= 0; } case LESS: { return Float.compare(floatval, floatval2) <= 0; } } return false; } private boolean compare_Double(int operation, double doubleval, Object value2) { if (operation == SUBSTRING) { return false; } double doubleval2; try { doubleval2 = Double.parseDouble(((String) value2).trim()); } catch (IllegalArgumentException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return Double.compare(doubleval, doubleval2) == 0; } case GREATER: { return Double.compare(doubleval, doubleval2) >= 0; } case LESS: { return Double.compare(doubleval, doubleval2) <= 0; } } return false; } private static final Class[] constructorType = new Class[] {String.class}; private boolean compare_Comparable(int operation, Comparable value1, Object value2) { if (operation == SUBSTRING) { return false; } Constructor constructor; try { constructor = value1.getClass().getConstructor(constructorType); } catch (NoSuchMethodException e) { return false; } try { if (!constructor.isAccessible()) AccessController.doPrivileged(new SetAccessibleAction( constructor)); value2 = constructor .newInstance(new Object[] {((String) value2).trim()}); } catch (IllegalAccessException e) { return false; } catch (InvocationTargetException e) { return false; } catch (InstantiationException e) { return false; } switch (operation) { case APPROX : case EQUAL : { return value1.compareTo(value2) == 0; } case GREATER: { return value1.compareTo(value2) >= 0; } case LESS: { return value1.compareTo(value2) <= 0; } } return false; } private boolean compare_Unknown(int operation, Object value1, Object value2) { if (operation == SUBSTRING) { return false; } Constructor constructor; try { constructor = value1.getClass().getConstructor(constructorType); } catch (NoSuchMethodException e) { return false; } try { if (!constructor.isAccessible()) AccessController.doPrivileged(new SetAccessibleAction( constructor)); value2 = constructor .newInstance(new Object[] {((String) value2).trim()}); } catch (IllegalAccessException e) { return false; } catch (InvocationTargetException e) { return false; } catch (InstantiationException e) { return false; } switch (operation) { case APPROX : case EQUAL : case GREATER: case LESS: { return value1.equals(value2); } } return false; } /** * Map a string for an APPROX (~=) comparison. * * This implementation removes white spaces. This is the minimum * implementation allowed by the OSGi spec. * * @param input Input string. * @return String ready for APPROX comparison. */ private static String approxString(String input) { boolean changed = false; char[] output = input.toCharArray(); int cursor = 0; for (int i = 0, length = output.length; i < length; i++) { char c = output[i]; if (Character.isWhitespace(c)) { changed = true; continue; } output[cursor] = c; cursor++; } return changed ? new String(output, 0, cursor) : input; } /** * Parser class for OSGi filter strings. This class parses the complete * filter string and builds a tree of Filter objects rooted at the * parent. */ private static class Parser { private final String filterstring; private final boolean ignoreCase; private final char[] filterChars; private int pos; Parser(String filterstring, boolean ignoreCase) { this.filterstring = filterstring; this.ignoreCase = ignoreCase; filterChars = filterstring.toCharArray(); pos = 0; } FilterImpl parse() throws InvalidSyntaxException { FilterImpl filter; try { filter = parse_filter(); } catch (ArrayIndexOutOfBoundsException e) { throw new InvalidSyntaxException("Filter ended abruptly", filterstring); } if (pos != filterChars.length) { throw new InvalidSyntaxException( "Extraneous trailing characters: " + filterstring.substring(pos), filterstring); } return filter; } private FilterImpl parse_filter() throws InvalidSyntaxException { FilterImpl filter; skipWhiteSpace(); if (filterChars[pos] != '(') { throw new InvalidSyntaxException("Missing '(': " + filterstring.substring(pos), filterstring); } pos++; filter = parse_filtercomp(); skipWhiteSpace(); if (filterChars[pos] != ')') { throw new InvalidSyntaxException("Missing ')': " + filterstring.substring(pos), filterstring); } pos++; skipWhiteSpace(); return filter; } private FilterImpl parse_filtercomp() throws InvalidSyntaxException { skipWhiteSpace(); char c = filterChars[pos]; switch (c) { case '&' : { pos++; return parse_and(); } case '|' : { pos++; return parse_or(); } case '!' : { pos++; return parse_not(); } } return parse_item(); } private FilterImpl parse_and() throws InvalidSyntaxException { int lookahead = pos; skipWhiteSpace(); if (filterChars[pos] != '(') { pos = lookahead - 1; return parse_item(); } List operands = new ArrayList(10); while (filterChars[pos] == '(') { FilterImpl child = parse_filter(); operands.add(child); } return new FilterImpl(FilterImpl.AND, null, operands .toArray(new FilterImpl[operands.size()])); } private FilterImpl parse_or() throws InvalidSyntaxException { int lookahead = pos; skipWhiteSpace(); if (filterChars[pos] != '(') { pos = lookahead - 1; return parse_item(); } List operands = new ArrayList(10); while (filterChars[pos] == '(') { FilterImpl child = parse_filter(); operands.add(child); } return new FilterImpl(FilterImpl.OR, null, operands .toArray(new FilterImpl[operands.size()])); } private FilterImpl parse_not() throws InvalidSyntaxException { int lookahead = pos; skipWhiteSpace(); if (filterChars[pos] != '(') { pos = lookahead - 1; return parse_item(); } FilterImpl child = parse_filter(); return new FilterImpl(FilterImpl.NOT, null, child); } private FilterImpl parse_item() throws InvalidSyntaxException { String attr = parse_attr(); skipWhiteSpace(); switch (filterChars[pos]) { case '*': { if (filterChars[pos + 1] == '>') { pos += 2; return new FilterImpl(FilterImpl.SUPERSET, attr, parse_value()); } break; } case '~' : { if (filterChars[pos + 1] == '=') { pos += 2; return new FilterImpl(FilterImpl.APPROX, attr, parse_value()); } break; } case '>' : { if (filterChars[pos + 1] == '=') { pos += 2; return new FilterImpl(FilterImpl.GREATER, attr, parse_value()); } break; } case '<' : { if (filterChars[pos + 1] == '=') { pos += 2; return new FilterImpl(FilterImpl.LESS, attr, parse_value()); } if (filterChars[pos + 1] == '*') { pos += 2; return new FilterImpl(FilterImpl.SUBSET, attr, parse_value()); } break; } case '=' : { if (filterChars[pos + 1] == '*') { int oldpos = pos; pos += 2; skipWhiteSpace(); if (filterChars[pos] == ')') { return new FilterImpl(FilterImpl.PRESENT, attr, null); } pos = oldpos; } pos++; Object string = parse_substring(); if (string instanceof String) { return new FilterImpl(FilterImpl.EQUAL, attr, string); } return new FilterImpl(FilterImpl.SUBSTRING, attr, string); } } throw new InvalidSyntaxException("Invalid operator: " + filterstring.substring(pos), filterstring); } private String parse_attr() throws InvalidSyntaxException { skipWhiteSpace(); int begin = pos; int end = pos; char c = filterChars[pos]; while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') { if (c == '<' && filterChars[pos+1] == '*') { break; } if (c == '*' && filterChars[pos+1] == '>') { break; } pos++; if (!Character.isWhitespace(c)) { end = pos; } c = filterChars[pos]; } int length = end - begin; if (length == 0) { throw new InvalidSyntaxException("Missing attr: " + filterstring.substring(pos), filterstring); } String str = new String(filterChars, begin, length); if (ignoreCase) { str = str.toLowerCase(); } return str; } private String parse_value() throws InvalidSyntaxException { StringBuffer sb = new StringBuffer(filterChars.length - pos); parseloop: while (true) { char c = filterChars[pos]; switch (c) { case ')' : { break parseloop; } case '(' : { throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring); } case '\\' : { pos++; c = filterChars[pos]; /* fall through into default */ } default : { sb.append(c); pos++; break; } } } if (sb.length() == 0) { throw new InvalidSyntaxException("Missing value: " + filterstring.substring(pos), filterstring); } return sb.toString(); } private Object parse_substring() throws InvalidSyntaxException { StringBuffer sb = new StringBuffer(filterChars.length - pos); List operands = new ArrayList(10); parseloop: while (true) { char c = filterChars[pos]; switch (c) { case ')' : { if (sb.length() > 0) { operands.add(sb.toString()); } break parseloop; } case '(' : { throw new InvalidSyntaxException("Invalid value: " + filterstring.substring(pos), filterstring); } case '*' : { if (sb.length() > 0) { operands.add(sb.toString()); } sb.setLength(0); operands.add(null); pos++; break; } case '\\' : { pos++; c = filterChars[pos]; /* fall through into default */ } default : { sb.append(c); pos++; break; } } } int size = operands.size(); if (size == 0) { return ""; } if (size == 1) { Object single = operands.get(0); if (single != null) { return single; } } return operands.toArray(new String[size]); } private void skipWhiteSpace() { for (int length = filterChars.length; (pos < length) && Character.isWhitespace(filterChars[pos]);) { pos++; } } } /** * This Dictionary is used for case-insensitive key lookup during filter * evaluation. This Dictionary implementation only supports the get * operation using a String key as no other operations are used by the * Filter implementation. */ private static class CaseInsensitiveDictionary extends Dictionary { private final Dictionary dictionary; private final String[] keys; /** * Create a case insensitive dictionary from the specified dictionary. * * @param dictionary * @throws IllegalArgumentException If dictionary contains * case variants of the same key name. */ CaseInsensitiveDictionary(Dictionary dictionary) { if (dictionary == null) { this.dictionary = null; this.keys = new String[0]; return; } this.dictionary = dictionary; List keyList = new ArrayList(dictionary.size()); for (Enumeration e = dictionary.keys(); e.hasMoreElements();) { Object k = e.nextElement(); if (k instanceof String) { String key = (String) k; for (Iterator i = keyList.iterator(); i.hasNext();) { if (key.equalsIgnoreCase((String) i.next())) { throw new IllegalArgumentException(); } } keyList.add(key); } } this.keys = (String[]) keyList.toArray(new String[keyList.size()]); } public Object get(Object o) { String k = (String) o; for (int i = 0, length = keys.length; i < length; i++) { String key = keys[i]; if (key.equalsIgnoreCase(k)) { return dictionary.get(key); } } return null; } public boolean isEmpty() { throw new UnsupportedOperationException(); } public Enumeration keys() { throw new UnsupportedOperationException(); } public Enumeration elements() { throw new UnsupportedOperationException(); } public Object put(Object key, Object value) { throw new UnsupportedOperationException(); } public Object remove(Object key) { throw new UnsupportedOperationException(); } public int size() { throw new UnsupportedOperationException(); } } private static class SetAccessibleAction implements PrivilegedAction { private final AccessibleObject accessible; SetAccessibleAction(AccessibleObject accessible) { this.accessible = accessible; } public Object run() { accessible.setAccessible(true); return null; } } /** * This Dictionary is used for key lookup from a ServiceReference during * filter evaluation. This Dictionary implementation only supports the get * operation using a String key as no other operations are used by the * Filter implementation. */ private static class ServiceReferenceDictionary extends Dictionary { private final ServiceReference reference; ServiceReferenceDictionary(ServiceReference reference) { this.reference = reference; } public Object get(Object key) { if (reference == null) { return null; } return reference.getProperty((String) key); } public boolean isEmpty() { throw new UnsupportedOperationException(); } public Enumeration keys() { throw new UnsupportedOperationException(); } public Enumeration elements() { throw new UnsupportedOperationException(); } public Object put(Object key, Object value) { throw new UnsupportedOperationException(); } public Object remove(Object key) { throw new UnsupportedOperationException(); } public int size() { throw new UnsupportedOperationException(); } } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/log/000077500000000000000000000000001155660342600234625ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/log/Logger.java000066400000000000000000000101541155660342600255450ustar00rootroot00000000000000/* * 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.felix.utils.log; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.log.LogService; import java.io.PrintStream; /** * Internal logger to be used in order to avoid a mandatory dependency on OSGi LogService. * It first tries to log to a log service implementation if there is one available and then fallback to System out/err * in case there is no log service available. */ public class Logger { public static final int LOG_ERROR = 1; public static final int LOG_WARNING = 2; public static final int LOG_INFO = 3; public static final int LOG_DEBUG = 4; /** * Bundle context. */ private final BundleContext m_context; private boolean m_isLogClassPresent; /** * Constructor. * * @param context bundle context */ public Logger(BundleContext context) { m_context = context; try { org.osgi.service.log.LogService.class.getName(); m_isLogClassPresent = true; } catch (NoClassDefFoundError ex) { m_isLogClassPresent = false; } } /** * @see LogService#log(int, String) */ public void log(int level, String message) { log(level, message, null); } /** * @see LogService#log(int, String, Throwable) */ public void log(int level, String message, Throwable exception) { if (!m_isLogClassPresent || !_log(level, message, exception)) { final PrintStream stream = getStream(level); stream.println(message); if (exception != null) { exception.printStackTrace(stream); } } } /** * Lookup the OSGi LogService and if available use it. */ private boolean _log(int level, String message, Throwable exception) { try { ServiceReference reference = null; reference = m_context.getServiceReference(LogService.class.getName()); if (reference != null) { final LogService logService = (LogService) m_context.getService(reference); if (logService != null) { logService.log(level, message, exception); m_context.ungetService(reference); return true; } } } catch (NoClassDefFoundError e) { //ignore } return false; } /** * Return the standard print streams to use depending on log level. * * @param level log level * @return print stream corresponding to log level */ private PrintStream getStream(int level) { switch (level) { case LOG_ERROR: System.err.print("ERROR: "); return System.err; case LOG_WARNING: System.err.print("WARNING: "); return System.err; case LOG_INFO: System.out.print("INFO: "); return System.out; case LOG_DEBUG: System.out.print("DEBUG: "); return System.out; default: System.out.print("UNKNOWN: "); return System.out; } } }felix-utils-1.1.0/src/main/java/org/apache/felix/utils/manifest/000077500000000000000000000000001155660342600245075ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/manifest/Attribute.java000066400000000000000000000022371155660342600273210ustar00rootroot00000000000000/* * 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.felix.utils.manifest; public class Attribute { private final String name; private final String value; public Attribute(String name, String value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/manifest/Clause.java000066400000000000000000000056341155660342600265760ustar00rootroot00000000000000/* * 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.felix.utils.manifest; public class Clause { private final String name; private final Directive[] directives; private final Attribute[] attributes; public Clause(String name, Directive[] directives, Attribute[] attributes) { this.name = name; this.directives = directives; this.attributes = attributes; } public String getName() { return name; } public Directive[] getDirectives() { return directives; } public Attribute[] getAttributes() { return attributes; } public String getDirective(String name) { for (int i = 0; i < directives.length; i++) { if (name.equals(directives[i].getName())) { return directives[i].getValue(); } } return null; } public String getAttribute(String name) { for (int i = 0; i < attributes.length; i++) { if (name.equals(attributes[i].getName())) { return attributes[i].getValue(); } } return null; } public String toString() { StringBuffer sb = new StringBuffer(); sb.append(name); for (int i = 0; directives != null && i < directives.length; i++) { sb.append(";").append(directives[i].getName()).append(":="); if (directives[i].getValue().indexOf(",") >= 0) { sb.append("\"").append(directives[i].getValue()).append("\""); } else { sb.append(directives[i].getValue()); } } for (int i = 0; attributes != null && i < attributes.length; i++) { sb.append(";").append(attributes[i].getName()).append("="); if (attributes[i].getValue().indexOf(",") >= 0) { sb.append("\"").append(attributes[i].getValue()).append("\""); } else { sb.append(attributes[i].getValue()); } } return sb.toString(); } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/manifest/Directive.java000066400000000000000000000022371155660342600272740ustar00rootroot00000000000000/* * 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.felix.utils.manifest; public class Directive { private final String name; private final String value; public Directive(String name, String value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/manifest/Parser.java000066400000000000000000000161251155660342600266130ustar00rootroot00000000000000/* * 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.felix.utils.manifest; import java.util.ArrayList; import java.util.List; public final class Parser { private Parser() { } public static Clause[] parseHeader(String header) throws IllegalArgumentException { Clause[] clauses = null; if (header != null) { if (header.length() == 0) { throw new IllegalArgumentException("The header cannot be an empty string."); } String[] ss = parseDelimitedString(header, ","); clauses = parseClauses(ss); } return (clauses == null) ? new Clause[0] : clauses; } public static Clause[] parseClauses(String[] ss) throws IllegalArgumentException { if (ss == null) { return null; } List completeList = new ArrayList(); for (int ssIdx = 0; ssIdx < ss.length; ssIdx++) { // Break string into semi-colon delimited pieces. String[] pieces = parseDelimitedString(ss[ssIdx], ";"); // Count the number of different clauses; clauses // will not have an '=' in their string. This assumes // that clauses come first, before directives and // attributes. int pathCount = 0; for (int pieceIdx = 0; pieceIdx < pieces.length; pieceIdx++) { if (pieces[pieceIdx].indexOf('=') >= 0) { break; } pathCount++; } // Error if no packages were specified. if (pathCount == 0) { throw new IllegalArgumentException("No path specified on clause: " + ss[ssIdx]); } // Parse the directives/attributes. Directive[] dirs = new Directive[pieces.length - pathCount]; Attribute[] attrs = new Attribute[pieces.length - pathCount]; int dirCount = 0, attrCount = 0; int idx = -1; String sep = null; for (int pieceIdx = pathCount; pieceIdx < pieces.length; pieceIdx++) { // Check if it is a directive. if ((idx = pieces[pieceIdx].indexOf(":=")) >= 0) { sep = ":="; } // Check if it is an attribute. else if ((idx = pieces[pieceIdx].indexOf("=")) >= 0) { sep = "="; } // It is an error. else { throw new IllegalArgumentException("Not a directive/attribute: " + ss[ssIdx]); } String key = pieces[pieceIdx].substring(0, idx).trim(); String value = pieces[pieceIdx].substring(idx + sep.length()).trim(); // Remove quotes, if value is quoted. if (value.startsWith("\"") && value.endsWith("\"")) { value = value.substring(1, value.length() - 1); } // Save the directive/attribute in the appropriate array. if (sep.equals(":=")) { dirs[dirCount++] = new Directive(key, value); } else { attrs[attrCount++] = new Attribute(key, value); } } // Shrink directive array. Directive[] dirsFinal = new Directive[dirCount]; System.arraycopy(dirs, 0, dirsFinal, 0, dirCount); // Shrink attribute array. Attribute[] attrsFinal = new Attribute[attrCount]; System.arraycopy(attrs, 0, attrsFinal, 0, attrCount); // Create package attributes for each package and // set directives/attributes. Add each package to // completel list of packages. Clause[] pkgs = new Clause[pathCount]; for (int pkgIdx = 0; pkgIdx < pathCount; pkgIdx++) { pkgs[pkgIdx] = new Clause(pieces[pkgIdx], dirsFinal, attrsFinal); completeList.add(pkgs[pkgIdx]); } } Clause[] pkgs = (Clause[]) completeList.toArray(new Clause[completeList.size()]); return pkgs; } /** * Parses delimited string and returns an array containing the tokens. This * parser obeys quotes, so the delimiter character will be ignored if it is * inside of a quote. This method assumes that the quote character is not * included in the set of delimiter characters. * @param value the delimited string to parse. * @param delim the characters delimiting the tokens. * @return an array of string tokens or null if there were no tokens. **/ public static String[] parseDelimitedString(String value, String delim) { if (value == null) { value = ""; } List list = new ArrayList(); int CHAR = 1; int DELIMITER = 2; int STARTQUOTE = 4; int ENDQUOTE = 8; StringBuffer sb = new StringBuffer(); int expecting = (CHAR | DELIMITER | STARTQUOTE); for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); boolean isDelimiter = (delim.indexOf(c) >= 0); boolean isQuote = (c == '"'); if (isDelimiter && ((expecting & DELIMITER) > 0)) { list.add(sb.toString().trim()); sb.delete(0, sb.length()); expecting = (CHAR | DELIMITER | STARTQUOTE); } else if (isQuote && ((expecting & STARTQUOTE) > 0)) { sb.append(c); expecting = CHAR | ENDQUOTE; } else if (isQuote && ((expecting & ENDQUOTE) > 0)) { sb.append(c); expecting = (CHAR | STARTQUOTE | DELIMITER); } else if ((expecting & CHAR) > 0) { sb.append(c); } else { throw new IllegalArgumentException("Invalid delimited string: " + value); } } if (sb.length() > 0) { list.add(sb.toString().trim()); } return (String[]) list.toArray(new String[list.size()]); } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/properties/000077500000000000000000000000001155660342600250755ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/properties/InterpolationHelper.java000066400000000000000000000175121155660342600317350ustar00rootroot00000000000000/* * 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.felix.utils.properties; import org.osgi.framework.BundleContext; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilterWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.net.URL; import java.util.*; /** *

* Enhancement of the standard Properties * managing the maintain of comments, etc. *

* * @author gnodet, jbonofre */ public class InterpolationHelper { private InterpolationHelper() { } private static final char ESCAPE_CHAR = '\\'; private static final String DELIM_START = "${"; private static final String DELIM_STOP = "}"; /** * Perform substitution on a property set * * @param properties the property set to perform substitution on */ public static void performSubstitution(Map properties) { performSubstitution(properties, null); } /** * Perform substitution on a property set * * @param properties the property set to perform substitution on */ public static void performSubstitution(Map properties, BundleContext context) { for (String name : properties.keySet()) { String value = properties.get(name); properties.put(name, substVars(value, name, null, properties, context)); } } /** *

* This method performs property variable substitution on the * specified value. If the specified value contains the syntax * ${<prop-name>}, where <prop-name> * refers to either a configuration property or a system property, * then the corresponding property value is substituted for the variable * placeholder. Multiple variable placeholders may exist in the * specified value as well as nested variable placeholders, which * are substituted from inner most to outer most. Configuration * properties override system properties. *

* @param val The string on which to perform property substitution. * @param currentKey The key of the property being evaluated used to * detect cycles. * @param cycleMap Map of variable references used to detect nested cycles. * @param configProps Set of configuration properties. * @param context the bundle context to retrieve properties from * @return The value of the specified string after system property substitution. * @throws IllegalArgumentException If there was a syntax error in the * property placeholder syntax or a recursive variable reference. **/ public static String substVars(String val, String currentKey, Map cycleMap, Map configProps, BundleContext context) throws IllegalArgumentException { if (cycleMap == null) { cycleMap = new HashMap(); } // Put the current key in the cycle map. cycleMap.put(currentKey, currentKey); // Assume we have a value that is something like: // "leading ${foo.${bar}} middle ${baz} trailing" // Find the first ending '}' variable delimiter, which // will correspond to the first deepest nested variable // placeholder. int stopDelim = val.indexOf(DELIM_STOP); while (stopDelim > 0 && val.charAt(stopDelim - 1) == ESCAPE_CHAR) { stopDelim = val.indexOf(DELIM_STOP, stopDelim + 1); } // Find the matching starting "${" variable delimiter // by looping until we find a start delimiter that is // greater than the stop delimiter we have found. int startDelim = val.indexOf(DELIM_START); while (stopDelim >= 0) { int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length()); if ((idx < 0) || (idx > stopDelim)) { break; } else if (idx < stopDelim) { startDelim = idx; } } // If we do not have a start or stop delimiter, then just // return the existing value. if ((startDelim < 0) || (stopDelim < 0)) { return unescape(val); } // At this point, we have found a variable placeholder so // we must perform a variable substitution on it. // Using the start and stop delimiter indices, extract // the first, deepest nested variable placeholder. String variable = val.substring(startDelim + DELIM_START.length(), stopDelim); // Verify that this is not a recursive variable reference. if (cycleMap.get(variable) != null) { throw new IllegalArgumentException("recursive variable reference: " + variable); } // Get the value of the deepest nested variable placeholder. // Try to configuration properties first. String substValue = (String) ((configProps != null) ? configProps.get(variable) : null); if (substValue == null) { if (variable.length() <= 0) { substValue = ""; } else if (context != null) { substValue = context.getProperty(variable); if (substValue == null) { substValue = ""; } } else { substValue = System.getProperty(variable, ""); } } // Remove the found variable from the cycle map, since // it may appear more than once in the value and we don't // want such situations to appear as a recursive reference. cycleMap.remove(variable); // Append the leading characters, the substituted value of // the variable, and the trailing characters to get the new // value. val = val.substring(0, startDelim) + substValue + val.substring(stopDelim + DELIM_STOP.length(), val.length()); // Now perform substitution again, since there could still // be substitutions to make. val = substVars(val, currentKey, cycleMap, configProps, context); // Remove escape characters preceding {, } and \ val = unescape(val); // Return the value. return val; } private static String unescape(String val) { int escape = val.indexOf(ESCAPE_CHAR); while (escape >= 0 && escape < val.length() - 1) { char c = val.charAt(escape + 1); if (c == '{' || c == '}' || c == ESCAPE_CHAR) { val = val.substring(0, escape) + val.substring(escape + 1); } escape = val.indexOf(ESCAPE_CHAR, escape + 1); } return val; } }felix-utils-1.1.0/src/main/java/org/apache/felix/utils/properties/Properties.java000066400000000000000000000703641155660342600301060ustar00rootroot00000000000000/* * 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.felix.utils.properties; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilterWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.net.URL; import java.util.AbstractMap; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; /** *

* Enhancement of the standard Properties * managing the maintain of comments, etc. *

* * @author gnodet, jbonofre */ public class Properties extends AbstractMap { /** Constant for the supported comment characters.*/ private static final String COMMENT_CHARS = "#!"; /** The list of possible key/value separators */ private static final char[] SEPARATORS = new char[] {'=', ':'}; /** The white space characters used as key/value separators. */ private static final char[] WHITE_SPACE = new char[] {' ', '\t', '\f'}; /** * The default encoding (ISO-8859-1 as specified by * http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html) */ private static final String DEFAULT_ENCODING = "ISO-8859-1"; /** Constant for the platform specific line separator.*/ private static final String LINE_SEPARATOR = System.getProperty("line.separator"); /** Constant for the radix of hex numbers.*/ private static final int HEX_RADIX = 16; /** Constant for the length of a unicode literal.*/ private static final int UNICODE_LEN = 4; private Map storage = new LinkedHashMap(); private Map layout = new LinkedHashMap(); private List header; private List footer; private File location; public Properties() { } public Properties(File location) throws IOException { this.location = location; if(location.exists()) load(location); } public void load(File location) throws IOException { InputStream is = new FileInputStream(location); try { load(is); } finally { is.close(); } } public void load(URL location) throws IOException { InputStream is = location.openStream(); try { load(is); } finally { is.close(); } } public void load(InputStream is) throws IOException { load(new InputStreamReader(is, DEFAULT_ENCODING)); } public void load(Reader reader) throws IOException { loadLayout(reader); } public void save() throws IOException { save(this.location); } public void save(File location) throws IOException { OutputStream os = new FileOutputStream(location); try { save(os); } finally { os.close(); } } public void save(OutputStream os) throws IOException { save(new OutputStreamWriter(os, DEFAULT_ENCODING)); } public void save(Writer writer) throws IOException { saveLayout(writer); } @Override public Set> entrySet() { return storage.entrySet(); } @Override public String put(String key, String value) { String old = storage.put(key, value); if (old == null || !old.equals(value)) { Layout l = layout.get(key); if (l != null) { l.clearValue(); } } return old; } @Override public String remove(Object key) { Layout l = layout.get(key); if (l != null) { l.clearValue(); } return storage.remove(key); } @Override public void clear() { for (Layout l : layout.values()) { l.clearValue(); } storage.clear(); } /** * Return the comment header. * * @return the comment header */ public List getHeader() { return header; } /** * Set the comment header. * * @param header the header to use */ public void setHeader(List header) { this.header = header; } /** * Return the comment footer. * * @return the comment footer */ public List getFooter() { return footer; } /** * Set the comment footer. * * @param footer the footer to use */ public void setFooter(List footer) { this.footer = footer; } /** * Reads a properties file and stores its internal structure. The found * properties will be added to the associated configuration object. * * @param in the reader to the properties file * @throws java.io.IOException if an error occurs */ protected void loadLayout(Reader in) throws IOException { PropertiesReader reader = new PropertiesReader(in); while (reader.nextProperty()) { storage.put(reader.getPropertyName(), reader.getPropertyValue()); int idx = checkHeaderComment(reader.getCommentLines()); layout.put(reader.getPropertyName(), new Layout(idx < reader.getCommentLines().size() ? new ArrayList(reader.getCommentLines().subList(idx, reader.getCommentLines().size())) : null, new ArrayList(reader.getValueLines()))); } footer = new ArrayList(reader.getCommentLines()); InterpolationHelper.performSubstitution(storage); } /** * Writes the properties file to the given writer, preserving as much of its * structure as possible. * * @param out the writer * @throws java.io.IOException if an error occurs */ protected void saveLayout(Writer out) throws IOException { PropertiesWriter writer = new PropertiesWriter(out); if (header != null) { for (String s : header) { writer.writeln(s); } } for (String key : storage.keySet()) { Layout l = layout.get(key); if (l != null && l.getCommentLines() != null) { for (String s : l.getCommentLines()) { writer.writeln(s); } } if (l != null && l.getValueLines() != null) { for (String s : l.getValueLines()) { writer.writeln(s); } } else { writer.writeProperty(key, storage.get(key)); } } if (footer != null) { for (String s : footer) { writer.writeln(s); } } writer.flush(); } /** * Checks if parts of the passed in comment can be used as header comment. * This method checks whether a header comment can be defined (i.e. whether * this is the first comment in the loaded file). If this is the case, it is * searched for the lates blank line. This line will mark the end of the * header comment. The return value is the index of the first line in the * passed in list, which does not belong to the header comment. * * @param commentLines the comment lines * @return the index of the next line after the header comment */ private int checkHeaderComment(List commentLines) { if (getHeader() == null && layout.isEmpty()) { // This is the first comment. Search for blank lines. int index = commentLines.size() - 1; while (index >= 0 && commentLines.get(index).length() > 0) { index--; } setHeader(new ArrayList(commentLines.subList(0, index + 1))); return index + 1; } else { return 0; } } /** * Tests whether a line is a comment, i.e. whether it starts with a comment * character. * * @param line the line * @return a flag if this is a comment line */ static boolean isCommentLine(String line) { String s = line.trim(); // blank lines are also treated as comment lines return s.length() < 1 || COMMENT_CHARS.indexOf(s.charAt(0)) >= 0; } /** *

Unescapes any Java literals found in the String to a * Writer.

This is a slightly modified version of the * StringEscapeUtils.unescapeJava() function in commons-lang that doesn't * drop escaped separators (i.e '\,'). * * @param str the String to unescape, may be null * @return the processed string * @throws IllegalArgumentException if the Writer is null */ protected static String unescapeJava(String str) { if (str == null) { return null; } int sz = str.length(); StringBuffer out = new StringBuffer(sz); StringBuffer unicode = new StringBuffer(UNICODE_LEN); boolean hadSlash = false; boolean inUnicode = false; for (int i = 0; i < sz; i++) { char ch = str.charAt(i); if (inUnicode) { // if in unicode, then we're reading unicode // values in somehow unicode.append(ch); if (unicode.length() == UNICODE_LEN) { // unicode now contains the four hex digits // which represents our unicode character try { int value = Integer.parseInt(unicode.toString(), HEX_RADIX); out.append((char) value); unicode.setLength(0); inUnicode = false; hadSlash = false; } catch (NumberFormatException nfe) { throw new IllegalArgumentException("Unable to parse unicode value: " + unicode, nfe); } } continue; } if (hadSlash) { // handle an escaped value hadSlash = false; switch (ch) { case '\\' : out.append('\\'); break; case '\'' : out.append('\''); break; case '\"' : out.append('"'); break; case 'r' : out.append('\r'); break; case 'f' : out.append('\f'); break; case 't' : out.append('\t'); break; case 'n' : out.append('\n'); break; case 'b' : out.append('\b'); break; case 'u' : // uh-oh, we're in unicode country.... inUnicode = true; break; default : out.append(ch); break; } continue; } else if (ch == '\\') { hadSlash = true; continue; } out.append(ch); } if (hadSlash) { // then we're in the weird case of a \ at the end of the // string, let's output it anyway. out.append('\\'); } return out.toString(); } /** *

Escapes the characters in a String using Java String rules.

* *

Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.)

* *

So a tab becomes the characters '\\' and * 't'.

* *

The only difference between Java strings and JavaScript strings * is that in JavaScript, a single quote must be escaped.

* *

Example: *

     * input string: He didn't say, "Stop!"
     * output string: He didn't say, \"Stop!\"
     * 
*

* * @param str String to escape values in, may be null * @return String with escaped values, null if null string input */ protected static String escapeJava(String str) { if (str == null) { return null; } int sz = str.length(); StringBuffer out = new StringBuffer(sz * 2); for (int i = 0; i < sz; i++) { char ch = str.charAt(i); // handle unicode if (ch > 0xfff) { out.append("\\u").append(hex(ch)); } else if (ch > 0xff) { out.append("\\u0").append(hex(ch)); } else if (ch > 0x7f) { out.append("\\u00").append(hex(ch)); } else if (ch < 32) { switch (ch) { case '\b' : out.append('\\'); out.append('b'); break; case '\n' : out.append('\\'); out.append('n'); break; case '\t' : out.append('\\'); out.append('t'); break; case '\f' : out.append('\\'); out.append('f'); break; case '\r' : out.append('\\'); out.append('r'); break; default : if (ch > 0xf) { out.append("\\u00").append(hex(ch)); } else { out.append("\\u000").append(hex(ch)); } break; } } else { switch (ch) { case '"' : out.append('\\'); out.append('"'); break; case '\\' : out.append('\\'); out.append('\\'); break; default : out.append(ch); break; } } } return out.toString(); } /** *

Returns an upper case hexadecimal String for the given * character.

* * @param ch The character to convert. * @return An upper case hexadecimal String */ protected static String hex(char ch) { return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH); } /** *

Checks if the value is in the given array.

* *

The method returns false if a null array is passed in.

* * @param array the array to search through * @param valueToFind the value to find * @return true if the array contains the object */ public static boolean contains(char[] array, char valueToFind) { if (array == null) { return false; } for (int i = 0; i < array.length; i++) { if (valueToFind == array[i]) { return true; } } return false; } /** * This class is used to read properties lines. These lines do * not terminate with new-line chars but rather when there is no * backslash sign a the end of the line. This is used to * concatenate multiple lines for readability. */ public static class PropertiesReader extends LineNumberReader { /** Stores the comment lines for the currently processed property.*/ private List commentLines; /** Stores the value lines for the currently processed property.*/ private List valueLines; /** Stores the name of the last read property.*/ private String propertyName; /** Stores the value of the last read property.*/ private String propertyValue; /** * Creates a new instance of PropertiesReader and sets * the underlaying reader and the list delimiter. * * @param reader the reader */ public PropertiesReader(Reader reader) { super(reader); commentLines = new ArrayList(); valueLines = new ArrayList(); } /** * Reads a property line. Returns null if Stream is * at EOF. Concatenates lines ending with "\". * Skips lines beginning with "#" or "!" and empty lines. * The return value is a property definition (<name> * = <value>) * * @return A string containing a property value or null * * @throws java.io.IOException in case of an I/O error */ public String readProperty() throws IOException { commentLines.clear(); valueLines.clear(); StringBuffer buffer = new StringBuffer(); while (true) { String line = readLine(); if (line == null) { // EOF return null; } if (isCommentLine(line)) { commentLines.add(line); continue; } valueLines.add(line); line = line.trim(); if (checkCombineLines(line)) { line = line.substring(0, line.length() - 1); buffer.append(line); } else { buffer.append(line); break; } } return buffer.toString(); } /** * Parses the next property from the input stream and stores the found * name and value in internal fields. These fields can be obtained using * the provided getter methods. The return value indicates whether EOF * was reached (false) or whether further properties are * available (true). * * @return a flag if further properties are available * @throws java.io.IOException if an error occurs */ public boolean nextProperty() throws IOException { String line = readProperty(); if (line == null) { return false; // EOF } // parse the line String[] property = parseProperty(line); propertyName = unescapeJava(property[0]); propertyValue = unescapeJava(property[1]); return true; } /** * Returns the comment lines that have been read for the last property. * * @return the comment lines for the last property returned by * readProperty() */ public List getCommentLines() { return commentLines; } /** * Returns the value lines that have been read for the last property. * * @return the raw value lines for the last property returned by * readProperty() */ public List getValueLines() { return valueLines; } /** * Returns the name of the last read property. This method can be called * after {@link #nextProperty()} was invoked and its * return value was true. * * @return the name of the last read property */ public String getPropertyName() { return propertyName; } /** * Returns the value of the last read property. This method can be * called after {@link #nextProperty()} was invoked and * its return value was true. * * @return the value of the last read property */ public String getPropertyValue() { return propertyValue; } /** * Checks if the passed in line should be combined with the following. * This is true, if the line ends with an odd number of backslashes. * * @param line the line * @return a flag if the lines should be combined */ private static boolean checkCombineLines(String line) { int bsCount = 0; for (int idx = line.length() - 1; idx >= 0 && line.charAt(idx) == '\\'; idx--) { bsCount++; } return bsCount % 2 != 0; } /** * Parse a property line and return the key and the value in an array. * * @param line the line to parse * @return an array with the property's key and value */ private static String[] parseProperty(String line) { // sorry for this spaghetti code, please replace it as soon as // possible with a regexp when the Java 1.3 requirement is dropped String[] result = new String[2]; StringBuffer key = new StringBuffer(); StringBuffer value = new StringBuffer(); // state of the automaton: // 0: key parsing // 1: antislash found while parsing the key // 2: separator crossing // 3: value parsing int state = 0; for (int pos = 0; pos < line.length(); pos++) { char c = line.charAt(pos); switch (state) { case 0: if (c == '\\') { state = 1; } else if (contains(WHITE_SPACE, c)) { // switch to the separator crossing state state = 2; } else if (contains(SEPARATORS, c)) { // switch to the value parsing state state = 3; } else { key.append(c); } break; case 1: if (contains(SEPARATORS, c) || contains(WHITE_SPACE, c)) { // this is an escaped separator or white space key.append(c); } else { // another escaped character, the '\' is preserved key.append('\\'); key.append(c); } // return to the key parsing state state = 0; break; case 2: if (contains(WHITE_SPACE, c)) { // do nothing, eat all white spaces state = 2; } else if (contains(SEPARATORS, c)) { // switch to the value parsing state state = 3; } else { // any other character indicates we encoutered the beginning of the value value.append(c); // switch to the value parsing state state = 3; } break; case 3: value.append(c); break; } } result[0] = key.toString().trim(); result[1] = value.toString().trim(); return result; } } // class PropertiesReader /** * This class is used to write properties lines. */ public static class PropertiesWriter extends FilterWriter { /** * Constructor. * * @param writer a Writer object providing the underlying stream */ public PropertiesWriter(Writer writer) { super(writer); } /** * Writes the given property and its value. * * @param key the property key * @param value the property value * @throws java.io.IOException if an error occurs */ public void writeProperty(String key, String value) throws IOException { write(escapeKey(key)); write(" = "); write(escapeJava(value)); writeln(null); } /** * Escape the separators in the key. * * @param key the key * @return the escaped key */ private String escapeKey(String key) { StringBuffer newkey = new StringBuffer(); for (int i = 0; i < key.length(); i++) { char c = key.charAt(i); if (contains(SEPARATORS, c) || contains(WHITE_SPACE, c)) { // escape the separator newkey.append('\\'); newkey.append(c); } else { newkey.append(c); } } return newkey.toString(); } /** * Helper method for writing a line with the platform specific line * ending. * * @param s the content of the line (may be null) * @throws java.io.IOException if an error occurs */ public void writeln(String s) throws IOException { if (s != null) { write(s); } write(LINE_SEPARATOR); } } // class PropertiesWriter /** * TODO */ protected static class Layout { private List commentLines; private List valueLines; public Layout() { } public Layout(List commentLines, List valueLines) { this.commentLines = commentLines; this.valueLines = valueLines; } public List getCommentLines() { return commentLines; } public void setCommentLines(List commentLines) { this.commentLines = commentLines; } public List getValueLines() { return valueLines; } public void setValueLines(List valueLines) { this.valueLines = valueLines; } public void clearValue() { this.valueLines = null; } } // class Layout }felix-utils-1.1.0/src/main/java/org/apache/felix/utils/version/000077500000000000000000000000001155660342600243665ustar00rootroot00000000000000felix-utils-1.1.0/src/main/java/org/apache/felix/utils/version/VersionCleaner.java000066400000000000000000000070471155660342600301600ustar00rootroot00000000000000/* * 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.felix.utils.version; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class VersionCleaner { private VersionCleaner() { } private static final Pattern FUZZY_VERSION = Pattern.compile("(\\d+)(\\.(\\d+)(\\.(\\d+))?)?([^a-zA-Z0-9](.*))?", Pattern.DOTALL); /** * Clean up version parameters. Other builders use more fuzzy definitions of * the version syntax. This method cleans up such a version to match an OSGi * version. * * @param version * @return */ public static String clean(String version) { if (version == null || version.length() == 0) { return "0.0.0"; } StringBuffer result = new StringBuffer(); Matcher m = FUZZY_VERSION.matcher(version); if (m.matches()) { String major = m.group(1); String minor = m.group(3); String micro = m.group(5); String qualifier = m.group(7); if (major != null) { result.append(major); if (minor != null) { result.append("."); result.append(minor); if (micro != null) { result.append("."); result.append(micro); if (qualifier != null) { result.append("."); cleanupModifier(result, qualifier); } } else if (qualifier != null) { result.append(".0."); cleanupModifier(result, qualifier); } else { result.append(".0"); } } else if (qualifier != null) { result.append(".0.0."); cleanupModifier(result, qualifier); } else { result.append(".0.0"); } } } else { result.append("0.0.0."); cleanupModifier(result, version); } return result.toString(); } private static void cleanupModifier(StringBuffer result, String modifier) { for (int i = 0; i < modifier.length(); i++) { char c = modifier.charAt(i); if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '-') result.append(c); else result.append('_'); } } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/version/VersionRange.java000066400000000000000000000311701155660342600276350ustar00rootroot00000000000000/* * 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.felix.utils.version; import java.io.Serializable; import org.osgi.framework.Version; public class VersionRange implements Serializable { /** * */ private static final long serialVersionUID = 1L; public static final Version INFINITE_VERSION = new Version( Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, "" ); public static final VersionRange ANY_VERSION = new VersionRange( false, Version.emptyVersion, INFINITE_VERSION, true ); public static final int EXACT = 0; public static final int MICRO = 1; public static final int MINOR = 2; public static final int MAJOR = 3; public static final int ANY = 40; private final boolean openFloor; private final Version floor; private final Version ceiling; private final boolean openCeiling; /** * Interval constructor * * @param openFloor Whether the lower bound of the range is inclusive (false) or exclusive (true). * @param floor The lower bound version of the range. * @param ceiling The upper bound version of the range. * @param openCeiling Whether the upper bound of the range is inclusive (false) or exclusive (true). */ public VersionRange( boolean openFloor, Version floor, Version ceiling, boolean openCeiling ) { this.openFloor = openFloor; this.floor = floor; this.ceiling = ceiling; this.openCeiling = openCeiling; checkRange(); } /** * atLeast constructor * * @param atLeast */ public VersionRange( Version atLeast ) { this( atLeast, false ); } /** * atLeast constructor * * @param atLeast */ public VersionRange( Version atLeast, boolean exact ) { this.openFloor = false; this.floor = atLeast; this.ceiling = exact ? atLeast : INFINITE_VERSION; this.openCeiling = exact ? false : true; checkRange(); } public VersionRange( String val ) throws IllegalArgumentException, NumberFormatException { this( val, false ); } public VersionRange( String val, boolean exact ) throws IllegalArgumentException, NumberFormatException { this( val, exact, true ); } public VersionRange( String val, boolean exact, boolean clean ) throws IllegalArgumentException, NumberFormatException { val = val.replaceAll( "\\s", "" ); val = val.replaceAll( "\"", "" ); int fst = val.charAt( 0 ); if ( fst == '[' ) { openFloor = false; } else if ( fst == '(' ) { openFloor = true; } else { openFloor = false; floor = VersionTable.getVersion( val, clean ); ceiling = exact ? floor : INFINITE_VERSION; openCeiling = exact ? false : true; return; } int lst = val.charAt( val.length() - 1 ); if ( lst == ']' ) { openCeiling = false; } else if ( lst == ')' ) { openCeiling = true; } else { throw new IllegalArgumentException( "illegal version range syntax " + val + ": range must end in ')' or ']'" ); } String inner = val.substring( 1, val.length() - 1 ); String[] floorCeiling = inner.split( "," ); if ( floorCeiling.length != 2 ) { throw new IllegalArgumentException( "illegal version range syntax " + "too many commas" ); } floor = VersionTable.getVersion( floorCeiling[0], clean ); ceiling = "*".equals( floorCeiling[1] ) ? INFINITE_VERSION : VersionTable.getVersion( floorCeiling[1], clean ); checkRange(); } public static VersionRange parseVersionRange( String val ) throws IllegalArgumentException, NumberFormatException { if ( val == null || val.trim().length() == 0 ) { return ANY_VERSION; } return new VersionRange( val ); } public Version getCeiling() { return ceiling; } public Version getFloor() { return floor; } public boolean isOpenCeiling() { return openCeiling; } public boolean isOpenFloor() { return openFloor; } public boolean isPointVersion() { return !openFloor && !openCeiling && floor.equals( ceiling ); } /** * test a version to see if it falls in the range * * @param version * @return */ public boolean contains( Version version ) { if ( version.equals( INFINITE_VERSION ) ) { return ceiling.equals( INFINITE_VERSION ); } else { return ( version.compareTo( floor ) > 0 && version.compareTo( ceiling ) < 0 ) || ( !openFloor && version.equals( floor ) ) || ( !openCeiling && version.equals( ceiling ) ); } } /* * (non-Javadoc) * * @see org.apache.aries.application.impl.VersionRange#intersect(VersionRange * range) */ public VersionRange intersect(VersionRange r) { // Use the highest minimum version. final Version newFloor; final boolean newOpenFloor; int minCompare = floor.compareTo(r.getFloor()); if (minCompare > 0) { newFloor = floor; newOpenFloor = openFloor; } else if (minCompare < 0) { newFloor = r.getFloor(); newOpenFloor = r.isOpenFloor(); } else { newFloor = floor; newOpenFloor = (openFloor || r.isOpenFloor()); } // Use the lowest maximum version. final Version newCeiling; final boolean newOpenCeiling; // null maximum version means unbounded, so the highest possible value. int maxCompare = ceiling.compareTo(r.getCeiling()); if (maxCompare < 0) { newCeiling = ceiling; newOpenCeiling = openCeiling; } else if (maxCompare > 0) { newCeiling = r.getCeiling(); newOpenCeiling = r.isOpenCeiling(); } else { newCeiling = ceiling; newOpenCeiling = (openCeiling || r.isOpenCeiling()); } VersionRange result; if (isRangeValid(newOpenFloor, newFloor, newCeiling, newOpenCeiling)) { result = new VersionRange(newOpenFloor, newFloor, newCeiling, newOpenCeiling); } else { result = null; } return result; } /** * Check if the supplied parameters describe a valid version range. * * @param floor * the minimum version. * @param openFloor * whether the minimum version is exclusive. * @param ceiling * the maximum version. * @param openCeiling * whether the maximum version is exclusive. * @return true is the range is valid; otherwise false. */ private static boolean isRangeValid(boolean openFloor, Version floor, Version ceiling, boolean openCeiling) { boolean result; int compare = floor.compareTo(ceiling); if (compare > 0) { // Minimum larger than maximum is invalid. result = false; } else if (compare == 0 && (openFloor || openCeiling)) { // If floor and ceiling are the same, and either are exclusive, no valid range // exists. result = false; } else { // Range is valid. result = true; } return result; } private void checkRange() { if (!isRangeValid(openFloor, floor, ceiling, openCeiling)) { throw new IllegalArgumentException("invalid version range: " + makeString(openFloor, floor, ceiling, openCeiling)); } } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ( ( ceiling == null ) ? 0 : ceiling.hashCode() ); result = prime * result + ( ( floor == null ) ? 0 : floor.hashCode() ); result = prime * result + ( openCeiling ? 1231 : 1237 ); result = prime * result + ( openFloor ? 1231 : 1237 ); return result; } public boolean equals( Object obj ) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; final VersionRange other = ( VersionRange ) obj; if ( ceiling == null ) { if ( other.ceiling != null ) return false; } else if ( !ceiling.equals( other.ceiling ) ) return false; if ( floor == null ) { if ( other.floor != null ) return false; } else if ( !floor.equals( other.floor ) ) return false; if ( openCeiling != other.openCeiling ) return false; if ( openFloor != other.openFloor ) return false; return true; } public String toString() { if ( ANY_VERSION.equals( this ) ) { return makeString( openFloor, Version.emptyVersion, INFINITE_VERSION, openCeiling ); } return makeString( openFloor, floor, ceiling, openCeiling ); } private String makeString( boolean openFloor, Version floor, Version ceiling, boolean openCeiling ) { StringBuffer vr = new StringBuffer( 32 ); if ( INFINITE_VERSION.equals( ceiling ) ) { vr.append( Version.emptyVersion.equals( floor ) ? "0" : floor.toString() ); } else { vr.append( openFloor ? "(" : "[" ); String floorStr = Version.emptyVersion.equals( floor ) ? "0" : floor.toString(); String ceilingStr = ceiling.toString(); vr.append( floorStr ).append( "," ).append( ceilingStr ); vr.append( openCeiling ? ")" : "]" ); } return vr.toString(); } public static VersionRange newInstance( Version pointVersion, int lowerBoundRule, int upperBoundRule ) { Version floor = null; switch ( lowerBoundRule ) { case ANY: floor = VersionTable.getVersion( 0, 0, 0 ); break; case MAJOR: floor = VersionTable.getVersion( pointVersion.getMajor(), 0, 0 ); break; case MINOR: floor = VersionTable.getVersion( pointVersion.getMajor(), pointVersion.getMinor(), 0 ); break; case MICRO: floor = VersionTable.getVersion( pointVersion.getMajor(), pointVersion.getMinor(), pointVersion.getMicro() ); break; case EXACT: floor = pointVersion; break; } Version ceiling = null; boolean openCeiling = true; switch ( upperBoundRule ) { case ANY: ceiling = INFINITE_VERSION; break; case MAJOR: ceiling = VersionTable.getVersion( pointVersion.getMajor() + 1, 0, 0 ); break; case MINOR: ceiling = VersionTable.getVersion( pointVersion.getMajor(), pointVersion.getMinor() + 1, 0 ); break; case MICRO: ceiling = VersionTable.getVersion( pointVersion.getMajor(), pointVersion.getMinor(), pointVersion.getMicro() + 1 ); break; case EXACT: ceiling = pointVersion; openCeiling = false; break; } return new VersionRange( false, floor, ceiling, openCeiling ); } } felix-utils-1.1.0/src/main/java/org/apache/felix/utils/version/VersionTable.java000066400000000000000000000051111155660342600276240ustar00rootroot00000000000000/* * 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.felix.utils.version; import java.util.WeakHashMap; import org.osgi.framework.Version; /** * Cache of Versions backed by a WeakHashMap to conserve memory. * * VersionTable.getVersion should be used in preference to new Version() or Version.parseVersion. * * @author dave * */ public final class VersionTable { private static final WeakHashMap versions = new WeakHashMap(); private VersionTable() { } public static Version getVersion(String version) { return getVersion( version, true ); } public static Version getVersion(String version, boolean clean) { if (clean) { version = VersionCleaner.clean(version); } synchronized( versions ) { Version v = (Version) versions.get(version); if ( v == null ) { v = Version.parseVersion(version); versions.put(version, v); } return v; } } public static Version getVersion(int major, int minor, int micro) { return getVersion(major, minor, micro, null); } public static Version getVersion(int major, int minor, int micro, String qualifier) { String key; if ( qualifier == null || qualifier.length() == 0 ) { key = major + "." + minor + "." + micro; } else { key = major + "." + minor + "." + micro + "." + qualifier; } synchronized( versions ) { Version v = (Version) versions.get(key); if ( v == null ) { v = new Version(major, minor, micro, qualifier); versions.put(key, v); } return v; } } } felix-utils-1.1.0/src/test/000077500000000000000000000000001155660342600155345ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/000077500000000000000000000000001155660342600164555ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/000077500000000000000000000000001155660342600172445ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/000077500000000000000000000000001155660342600204655ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/000077500000000000000000000000001155660342600215745ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/utils/000077500000000000000000000000001155660342600227345ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/utils/filter/000077500000000000000000000000001155660342600242215ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/utils/filter/FilterImplTest.java000066400000000000000000000110151155660342600277710ustar00rootroot00000000000000/* * 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.felix.utils.filter; import java.util.Dictionary; import java.util.Hashtable; import junit.framework.TestCase; import org.osgi.framework.Version; public class FilterImplTest extends TestCase { public void testStandardLDAP() throws Exception { FilterImpl filterImpl = FilterImpl.newInstance( "(&(package=org.eclipse.core.runtime)(version>=0.0.0)(common=split))"); Dictionary dict = new Hashtable(); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", "0.0.0"); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); dict = new Hashtable(); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", "0.0.0"); dict.put("common", "split-wrong"); assertFalse(filterImpl.match(dict)); } public void testNoneStandardLDAPOperators() throws Exception { FilterImpl filterImpl = FilterImpl.newInstance( "(&(package=org.eclipse.core.runtime)(version>=0.0.0)(common=split)(mandatory:<*common,test))"); Dictionary dict = new Hashtable(); dict.put("somethindifferent", "sonstwas"); assertFalse(filterImpl.match(dict)); dict = new Hashtable(); dict.put("mandatory:", "common"); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); dict = new Hashtable(); dict.put("mandatory:", "common,test"); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); dict = new Hashtable(); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); filterImpl = FilterImpl.newInstance( "(&(package=org.eclipse.core.runtime)(version>=0.0.0)(common=split)(mandatory:*>common))"); dict = new Hashtable(); dict.put("mandatory:", "common"); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); dict = new Hashtable(); dict.put("mandatory:", "common,test"); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); filterImpl = FilterImpl.newInstance( "(&(package=org.eclipse.core.runtime)(version>=0.0.0)(common=split)(mandatory:*>common,test))"); dict = new Hashtable(); dict.put("mandatory:", "common"); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertFalse(filterImpl.match(dict)); dict = new Hashtable(); dict.put("mandatory:", "common,test"); dict.put("package", "org.eclipse.core.runtime"); dict.put("version", new Version("0.0.0")); dict.put("common", "split"); assertTrue(filterImpl.match(dict)); } public void testCaseSensitive() throws Exception { FilterImpl filterImpl = FilterImpl.newInstance("(&(package=org.eclipse.core.runtime))"); Dictionary dict = new Hashtable(); dict.put("PACKAGE", "org.eclipse.core.runtime"); assertTrue(filterImpl.match(dict)); dict = new Hashtable(); dict.put("PACKAGE", "org.eclipse.core.runtime"); assertFalse(filterImpl.matchCase(dict)); } }felix-utils-1.1.0/src/test/java/org/apache/felix/utils/manifest/000077500000000000000000000000001155660342600245425ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/utils/manifest/ParserTest.java000066400000000000000000000067671155660342600275210ustar00rootroot00000000000000/* * 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.felix.utils.manifest; import junit.framework.TestCase; public class ParserTest extends TestCase { public void testSimple() throws Exception { Clause[] paths = Parser.parseHeader("/foo.xml, /foo/bar.xml"); assertEquals(2, paths.length); assertEquals("/foo.xml", paths[0].getName()); assertEquals(0, paths[0].getAttributes().length); assertEquals(0, paths[0].getDirectives().length); assertEquals("/foo/bar.xml", paths[1].getName()); assertEquals(0, paths[1].getAttributes().length); assertEquals(0, paths[1].getDirectives().length); } public void testComplex() throws Exception { Clause[] paths = Parser.parseHeader("OSGI-INF/blueprint/comp1_named.xml;ignored-directive:=true,OSGI-INF/blueprint/comp2_named.xml;some-other-attribute=1"); assertEquals(2, paths.length); assertEquals("OSGI-INF/blueprint/comp1_named.xml", paths[0].getName()); assertEquals(0, paths[0].getAttributes().length); assertEquals(1, paths[0].getDirectives().length); assertEquals("true", paths[0].getDirective("ignored-directive")); assertEquals("OSGI-INF/blueprint/comp2_named.xml", paths[1].getName()); assertEquals(1, paths[1].getAttributes().length); assertEquals("1", paths[1].getAttribute("some-other-attribute")); assertEquals(0, paths[1].getDirectives().length); } public void testPaths() throws Exception { Clause[] paths = Parser.parseHeader("OSGI-INF/blueprint/comp1_named.xml;ignored-directive:=true,OSGI-INF/blueprint/comp2_named.xml;foo.xml;a=b;1:=2;c:=d;4=5"); assertEquals(3, paths.length); assertEquals("OSGI-INF/blueprint/comp1_named.xml", paths[0].getName()); assertEquals(0, paths[0].getAttributes().length); assertEquals(1, paths[0].getDirectives().length); assertEquals("true", paths[0].getDirective("ignored-directive")); assertEquals("OSGI-INF/blueprint/comp2_named.xml", paths[1].getName()); assertEquals(2, paths[1].getAttributes().length); assertEquals("b", paths[1].getAttribute("a")); assertEquals("5", paths[1].getAttribute("4")); assertEquals(2, paths[1].getDirectives().length); assertEquals("d", paths[1].getDirective("c")); assertEquals("2", paths[1].getDirective("1")); assertEquals("foo.xml", paths[2].getName()); assertEquals(2, paths[2].getAttributes().length); assertEquals("b", paths[2].getAttribute("a")); assertEquals("5", paths[2].getAttribute("4")); assertEquals(2, paths[2].getDirectives().length); assertEquals("d", paths[2].getDirective("c")); assertEquals("2", paths[2].getDirective("1")); } } felix-utils-1.1.0/src/test/java/org/apache/felix/utils/properties/000077500000000000000000000000001155660342600251305ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/utils/properties/InterpolationHelperTest.java000066400000000000000000000100061155660342600326170ustar00rootroot00000000000000/* * 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.felix.utils.properties; import junit.framework.TestCase; import java.util.Enumeration; import java.util.Hashtable; public class InterpolationHelperTest extends TestCase { private MockBundleContext context; protected void setUp() throws Exception { context = new MockBundleContext(); } public void testBasicSubstitution() { System.setProperty("value1", "sub_value1"); Hashtable props = new Hashtable(); props.put("key0", "value0"); props.put("key1", "${value1}"); props.put("key2", "${value2}"); for (Enumeration e = props.keys(); e.hasMoreElements();) { String name = (String) e.nextElement(); props.put(name, InterpolationHelper.substVars((String) props.get(name), name, null, props, context)); } assertEquals("value0", props.get("key0")); assertEquals("sub_value1", props.get("key1")); assertEquals("", props.get("key2")); } public void testBasicSubstitutionWithContext() { System.setProperty("value1", "sub_value1"); System.setProperty("value2", "sub_value2"); context.setProperty("value3", "context_value1"); context.setProperty("value2", "context_value2"); Hashtable props = new Hashtable(); props.put("key0", "value0"); props.put("key1", "${value1}"); props.put("key2", "${value2}"); props.put("key3", "${value3}"); for (Enumeration e = props.keys(); e.hasMoreElements();) { String name = (String) e.nextElement(); props.put(name, InterpolationHelper.substVars((String) props.get(name), name, null, props, context)); } assertEquals("value0", props.get("key0")); assertEquals("sub_value1", props.get("key1")); assertEquals("context_value2", props.get("key2")); assertEquals("context_value1", props.get("key3")); } public void testSubstitutionFailures() { assertEquals("a}", InterpolationHelper.substVars("a}", "b", null, new Hashtable(), context)); assertEquals("${a", InterpolationHelper.substVars("${a", "b", null, new Hashtable(), context)); } public void testEmptyVariable() { assertEquals("", InterpolationHelper.substVars("${}", "b", null, new Hashtable(), context)); } public void testInnerSubst() { Hashtable props = new Hashtable(); props.put("a", "b"); props.put("b", "c"); assertEquals("c", InterpolationHelper.substVars("${${a}}", "z", null, props, context)); } public void testSubstLoop() { try { InterpolationHelper.substVars("${a}", "a", null, new Hashtable(), context); fail("Should have thrown an exception"); } catch (IllegalArgumentException e) { // expected } } public void testSubstitutionEscape() { assertEquals("${a}", InterpolationHelper.substVars("$\\{a${#}\\}", "b", null, new Hashtable(), context)); assertEquals("${a}", InterpolationHelper.substVars("$\\{a\\}${#}", "b", null, new Hashtable(), context)); assertEquals("${a}", InterpolationHelper.substVars("$\\{a\\}", "b", null, new Hashtable(), context)); } } felix-utils-1.1.0/src/test/java/org/apache/felix/utils/properties/MockBundleContext.java000066400000000000000000000106201155660342600313620ustar00rootroot00000000000000/* * 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.felix.utils.properties; import java.io.File; import java.io.InputStream; import java.util.Properties; import java.util.Dictionary; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.BundleListener; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkListener; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; public class MockBundleContext implements BundleContext { private Properties properties = new Properties(); public void setProperty(String name, String value) { this.properties.setProperty(name, value); } public String getProperty(String name) { String value = this.properties.getProperty(name); if (value == null) { value = System.getProperty(name); } return value; } public Bundle getBundle() { throw new UnsupportedOperationException(); } public Bundle installBundle(String s) throws BundleException { throw new UnsupportedOperationException(); } public Bundle installBundle(String s, InputStream stream) throws BundleException { throw new UnsupportedOperationException(); } public Bundle getBundle(long l) { throw new UnsupportedOperationException(); } public Bundle[] getBundles() { throw new UnsupportedOperationException(); } public void addServiceListener(ServiceListener listener, String s) throws InvalidSyntaxException { throw new UnsupportedOperationException(); } public void addServiceListener(ServiceListener listener) { throw new UnsupportedOperationException(); } public void removeServiceListener(ServiceListener listener) { throw new UnsupportedOperationException(); } public void addBundleListener(BundleListener listener) { throw new UnsupportedOperationException(); } public void removeBundleListener(BundleListener listener) { throw new UnsupportedOperationException(); } public void addFrameworkListener(FrameworkListener listener) { throw new UnsupportedOperationException(); } public void removeFrameworkListener(FrameworkListener listener) { throw new UnsupportedOperationException(); } public ServiceRegistration registerService(String[] strings, Object o, Dictionary dictionary) { throw new UnsupportedOperationException(); } public ServiceRegistration registerService(String s, Object o, Dictionary dictionary) { throw new UnsupportedOperationException(); } public ServiceReference[] getServiceReferences(String s, String s1) throws InvalidSyntaxException { throw new UnsupportedOperationException(); } public ServiceReference[] getAllServiceReferences(String s, String s1) throws InvalidSyntaxException { throw new UnsupportedOperationException(); } public ServiceReference getServiceReference(String s) { throw new UnsupportedOperationException(); } public Object getService(ServiceReference reference) { throw new UnsupportedOperationException(); } public boolean ungetService(ServiceReference reference) { throw new UnsupportedOperationException(); } public File getDataFile(String s) { throw new UnsupportedOperationException(); } public Filter createFilter(String s) throws InvalidSyntaxException { throw new UnsupportedOperationException(); } } felix-utils-1.1.0/src/test/java/org/apache/felix/utils/properties/PropertiesTest.java000066400000000000000000000053021155660342600307670ustar00rootroot00000000000000/* * 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.felix.utils.properties; import java.io.IOException; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import junit.framework.TestCase; /** *

* Unit tests on Properties. *

* * @author jbonofre */ public class PropertiesTest extends TestCase { private final static String TEST_PROPERTIES_FILE = "test.properties"; private Properties properties; /* * (non-Javadoc) * @see junit.framework.TestCase#setUp() */ public void setUp() throws Exception { properties = new Properties(); properties.load(this.getClass().getClassLoader().getResourceAsStream(TEST_PROPERTIES_FILE)); } /** *

* Test getting property. *

* * @throws Exception */ public void testGettingProperty() throws Exception { assertEquals("test", properties.get("test")); } public void testLoadSave() throws IOException { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.println("# "); pw.println("# The Main "); pw.println("# "); pw.println("# Comment "); pw.println("# "); pw.println(""); pw.println("# Another comment"); pw.println(""); pw.println("# A value comment"); pw.println("key1 = val1"); pw.println(""); pw.println("# Another value comment"); pw.println("key2 = ${key1}/foo"); pw.println(""); pw.println("# A third comment"); pw.println("key3 = val3"); pw.println(""); Properties props = new Properties(); props.load(new StringReader(sw.toString())); props.save(System.err); System.err.println("====="); props.put("key2", props.get("key2")); props.put("key3", "foo"); props.save(System.err); System.err.println("====="); } } felix-utils-1.1.0/src/test/java/org/apache/felix/utils/version/000077500000000000000000000000001155660342600244215ustar00rootroot00000000000000felix-utils-1.1.0/src/test/java/org/apache/felix/utils/version/VersionCleanerTest.java000066400000000000000000000052431155660342600310470ustar00rootroot00000000000000/* * 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.felix.utils.version; import junit.framework.TestCase; public class VersionCleanerTest extends TestCase { public void testConvertVersionToOsgi() { String osgiVersion; osgiVersion = VersionCleaner.clean(null); assertEquals("0.0.0", osgiVersion); osgiVersion = VersionCleaner.clean(""); assertEquals("0.0.0", osgiVersion); osgiVersion = VersionCleaner.clean("2.1.0-SNAPSHOT"); assertEquals("2.1.0.SNAPSHOT", osgiVersion); osgiVersion = VersionCleaner.clean("2.1-SNAPSHOT"); assertEquals("2.1.0.SNAPSHOT", osgiVersion); osgiVersion = VersionCleaner.clean("2-SNAPSHOT"); assertEquals("2.0.0.SNAPSHOT", osgiVersion); osgiVersion = VersionCleaner.clean("2"); assertEquals("2.0.0", osgiVersion); osgiVersion = VersionCleaner.clean("2.1"); assertEquals("2.1.0", osgiVersion); osgiVersion = VersionCleaner.clean("2.1.3"); assertEquals("2.1.3", osgiVersion); osgiVersion = VersionCleaner.clean("2.1.3.4"); assertEquals("2.1.3.4", osgiVersion); osgiVersion = VersionCleaner.clean("4aug2000r7-dev"); assertEquals("0.0.0.4aug2000r7-dev", osgiVersion); osgiVersion = VersionCleaner.clean("1.1-alpha-2"); assertEquals("1.1.0.alpha-2", osgiVersion); osgiVersion = VersionCleaner.clean("1.0-alpha-16-20070122.203121-13"); assertEquals("1.0.0.alpha-16-20070122_203121-13", osgiVersion); osgiVersion = VersionCleaner.clean("1.0-20070119.021432-1"); assertEquals("1.0.0.20070119_021432-1", osgiVersion); osgiVersion = VersionCleaner.clean("1-20070119.021432-1"); assertEquals("1.0.0.20070119_021432-1", osgiVersion); osgiVersion = VersionCleaner.clean("1.4.1-20070217.082013-7"); assertEquals("1.4.1.20070217_082013-7", osgiVersion); } } felix-utils-1.1.0/src/test/java/org/apache/felix/utils/version/VersionRangeTest.java000066400000000000000000000207701155660342600305340ustar00rootroot00000000000000/* * 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.felix.utils.version; import junit.framework.TestCase; import org.osgi.framework.Version; public class VersionRangeTest extends TestCase { public void testVersionRange() throws Exception { String version1 = "[1.2.3, 4.5.6]"; String version2 = "(1, 2]"; String version3 = "[2,4)"; String version4 = "(1,2)"; String version5 = "2"; String version6 = "2.3"; String version7 = "[1.2.3.q, 2.3.4.p)"; String version8 = "1.2.2.5"; String version9 = "a.b.c"; String version10 = null; String version11 = ""; String version12 = "\"[1.2.3, 4.5.6]\""; VersionRange vr = new VersionRange(version1); assertEquals("The value is wrong", "1.2.3", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "4.5.6", vr.getCeiling().toString()); assertFalse("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version2); assertEquals("The value is wrong", "1.0.0", vr.getFloor().toString()); assertTrue("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "2.0.0", vr.getCeiling().toString()); assertFalse("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version3); assertEquals("The value is wrong", "2.0.0", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "4.0.0", vr.getCeiling().toString()); assertTrue("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version4); assertEquals("The value is wrong", "1.0.0", vr.getFloor().toString()); assertTrue("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "2.0.0", vr.getCeiling().toString()); assertTrue("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version5); assertEquals("The value is wrong", "2.0.0", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", VersionRange.INFINITE_VERSION, vr.getCeiling()); assertTrue("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version6, true); assertEquals("The value is wrong", "2.3.0", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "2.3.0", vr.getCeiling().toString()); assertFalse("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version7); assertEquals("The value is wrong", "1.2.3.q", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "2.3.4.p", vr.getCeiling().toString()); assertTrue("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version8); assertEquals("The value is wrong", "1.2.2.5", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", VersionRange.INFINITE_VERSION, vr.getCeiling()); assertTrue("The value is wrong", vr.isOpenCeiling()); boolean exception = false; try { vr = new VersionRange(version9, false, false); } catch (Exception e) { exception = true; } assertTrue("The value is wrong", exception); boolean exceptionNull = false; try { vr = new VersionRange(version10, false, false); } catch (Exception e) { exceptionNull = true; } assertTrue("The value is wrong", exceptionNull); // empty version should be defaulted to >=0.0.0 vr = VersionRange.parseVersionRange(version11); assertEquals("The value is wrong", "0.0.0", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", VersionRange.INFINITE_VERSION, vr.getCeiling()); assertTrue("The value is wrong", vr.isOpenCeiling()); vr = new VersionRange(version12); assertEquals("The value is wrong", "1.2.3", vr.getFloor().toString()); assertFalse("The value is wrong", vr.isOpenFloor()); assertEquals("The value is wrong", "4.5.6", vr.getCeiling().toString()); assertFalse("The value is wrong", vr.isOpenCeiling()); } public void testInvalidVersions() throws Exception { try { new VersionRange("a", false, false); assertTrue("Should have thrown an exception", false); } catch (IllegalArgumentException e) { } } public void testMatches() { VersionRange vr = new VersionRange("[1.0.0, 2.0.0]"); assertFalse(vr.contains(new Version(0, 9, 0))); assertFalse(vr.contains(new Version(2, 1, 0))); assertTrue(vr.contains(new Version(2, 0, 0))); assertTrue(vr.contains(new Version(1, 0, 0))); assertTrue(vr.contains(new Version(1, 5, 0))); vr = new VersionRange("[1.0.0, 2.0.0)"); assertFalse(vr.contains(new Version(0, 9, 0))); assertFalse(vr.contains(new Version(2, 1, 0))); assertFalse(vr.contains(new Version(2, 0, 0))); assertTrue(vr.contains(new Version(1, 0, 0))); assertTrue(vr.contains(new Version(1, 5, 0))); vr = new VersionRange("(1.0.0, 2.0.0)"); assertFalse(vr.contains(new Version(0, 9, 0))); assertFalse(vr.contains(new Version(2, 1, 0))); assertFalse(vr.contains(new Version(2, 0, 0))); assertFalse(vr.contains(new Version(1, 0, 0))); assertTrue(vr.contains(new Version(1, 5, 0))); vr = new VersionRange("[1.0.0, 1.0.0]"); assertFalse(vr.contains(new Version(0, 9, 0))); assertFalse(vr.contains(new Version(2, 0, 0))); assertTrue(vr.contains(new Version(1, 0, 0))); assertFalse(vr.contains(new Version(1, 5, 0))); assertFalse(vr.contains(new Version(1, 9, 9))); } public void testIntersectVersionRange_Valid1() { VersionRange v1 = new VersionRange("[1.0.0,3.0.0]"); VersionRange v2 = new VersionRange("[2.0.0,3.0.0)"); VersionRange result = v1.intersect(v2); assertNotNull(result); assertEquals("[2.0.0,3.0.0)", result.toString()); } public void testIntersectVersionRange_Valid2() { VersionRange v1 = new VersionRange("[1.0.0,3.0.0)"); VersionRange v2 = new VersionRange("(2.0.0,3.0.0]"); VersionRange result = v1.intersect(v2); assertNotNull(result); assertEquals("(2.0.0,3.0.0)", result.toString()); } public void testIntersectVersionRange_Valid3() { VersionRange v1 = new VersionRange("[2.0.0,2.0.0]"); VersionRange v2 = new VersionRange("[1.0.0,3.0.0]"); VersionRange result = v1.intersect(v2); assertNotNull(result); assertEquals("[2.0.0,2.0.0]", result.toString()); } public void testIntersectVersionRange_Invalid1() { VersionRange v1 = new VersionRange("[1.0.0,2.0.0]"); VersionRange v2 = new VersionRange("(2.0.0,3.0.0]"); VersionRange result = v1.intersect(v2); assertNull(result); } public void testIntersectVersionRange_Invalid2() { VersionRange v1 = new VersionRange("[1.0.0,2.0.0)"); VersionRange v2 = new VersionRange("[2.0.0,3.0.0]"); VersionRange result = v1.intersect(v2); assertNull(result); } public void testIntersectVersionRange_Invalid3() { VersionRange v1 = new VersionRange("[1.0.0,1.0.0]"); VersionRange v2 = new VersionRange("[2.0.0,2.0.0]"); VersionRange result = v1.intersect(v2); assertNull(result); } } felix-utils-1.1.0/src/test/resources/000077500000000000000000000000001155660342600175465ustar00rootroot00000000000000felix-utils-1.1.0/src/test/resources/test.properties000066400000000000000000000017761155660342600226560ustar00rootroot00000000000000##--------------------------------------------------------------------------- ## 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. ##--------------------------------------------------------------------------- # # test.properties # Used in the PropertiesTest # test=test