You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2008/09/01 17:08:10 UTC
svn commit: r690991 [6/20] - in /cxf/sandbox/dosgi: ./ discovery/
discovery/local/ discovery/local/src/ discovery/local/src/main/
discovery/local/src/main/java/ discovery/local/src/main/java/org/
discovery/local/src/main/java/org/apache/ discovery/loca...
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Felix.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Felix.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FelixBundle.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FelixBundle.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FelixBundle.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FelixBundle.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,26 @@
+/*
+ * 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.framework;
+
+import org.osgi.framework.Bundle;
+
+abstract class FelixBundle implements Bundle
+{
+ /* package private */ abstract BundleInfo getInfo();
+}
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FelixBundle.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FelixBundle.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FilterImpl.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FilterImpl.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FilterImpl.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,316 @@
+/*
+ * 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.framework;
+
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.util.*;
+import java.lang.ref.SoftReference;
+
+import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.util.ldap.*;
+import org.osgi.framework.*;
+
+/**
+ * This class implements an RFC 1960-based filter. The syntax of the
+ * filter string is the string representation of LDAP search filters
+ * as defined in RFC 1960. These filters are used to search for services
+ * and to track services using <tt>ServiceTracker</tt> objects.
+**/
+public class FilterImpl implements Filter
+{
+ private static final WeakHashMap m_programCache = new WeakHashMap();
+ private final ThreadLocal m_cache = new ThreadLocal();
+ private final Logger m_logger;
+ private final Object[] m_program;
+ private volatile String m_toString;
+
+// TODO: FilterImpl needs a logger, this is a hack for FrameworkUtil.
+ public FilterImpl(String expr) throws InvalidSyntaxException
+ {
+ this(null, expr);
+ }
+
+ /**
+ * Construct a filter for a given filter expression string.
+ * @param expr the filter expression string for the filter.
+ **/
+ public FilterImpl(Logger logger, String expr) throws InvalidSyntaxException
+ {
+ m_logger = logger;
+ if (expr == null)
+ {
+ throw new InvalidSyntaxException("Filter cannot be null", null);
+ }
+ Object[] program = null;
+ synchronized (m_programCache)
+ {
+ program = (Object[]) m_programCache.get(expr);
+ }
+ if (program == null)
+ {
+ CharArrayReader car = new CharArrayReader(expr.toCharArray());
+ LdapLexer lexer = new LdapLexer(car);
+ Parser parser = new Parser(lexer);
+ try
+ {
+ if (!parser.start())
+ {
+ throw new InvalidSyntaxException(
+ "Failed to parse LDAP query.", expr);
+ }
+ }
+ catch (ParseException ex)
+ {
+ throw new InvalidSyntaxException(
+ ex.getMessage(), expr);
+ }
+ catch (IOException ex)
+ {
+ throw new InvalidSyntaxException(
+ ex.getMessage(), expr);
+ }
+ program = parser.getProgram();
+ synchronized (m_programCache)
+ {
+ if (!m_programCache.containsKey(expr))
+ {
+ m_programCache.put(expr, program);
+ }
+ }
+ }
+ m_program = program;
+ }
+
+ /**
+ * Compares the <tt>Filter</tt> object to another.
+ * @param o the object to compare this <tt>Filter</tt> against.
+ * @return If the other object is a <tt>Filter</tt> object, it
+ * returns <tt>this.toString().equals(obj.toString())</tt>;
+ * <tt>false</tt> otherwise.
+ **/
+ public boolean equals(Object o)
+ {
+ if (o == null)
+ {
+ return false;
+ }
+ else if (o instanceof Filter)
+ {
+ return toString().equals(o.toString());
+ }
+ return false;
+ }
+
+ /**
+ * Returns the hash code for the <tt>Filter</tt> object.
+ * @return The value <tt>this.toString().hashCode()</tt>.
+ **/
+ public int hashCode()
+ {
+ return toString().hashCode();
+ }
+
+ private boolean match(Dictionary dict, ServiceReference ref, boolean caseSensitive)
+ throws IllegalArgumentException
+ {
+ SoftReference tupleRef = (SoftReference) m_cache.get();
+ Evaluator evaluator = null;
+ SimpleMapper mapper = null;
+ Object[] tuple = null;
+
+ if (tupleRef != null)
+ {
+ tuple = (Object[]) tupleRef.get();
+ }
+
+ if (tuple == null)
+ {
+ evaluator = new Evaluator(m_program);
+ mapper = new SimpleMapper();
+ }
+ else
+ {
+ evaluator = (Evaluator) tuple[0];
+ mapper = (SimpleMapper) tuple[1];
+ m_cache.set(null);
+ }
+
+ try
+ {
+ if (dict != null)
+ {
+ mapper.setSource(dict, caseSensitive);
+ }
+ else
+ {
+ mapper.setSource(ref);
+ }
+
+ return evaluator.evaluate(mapper);
+ }
+ catch (AttributeNotFoundException ex)
+ {
+ log(Logger.LOG_DEBUG, "FilterImpl: Attribute not found.", ex);
+ }
+ catch (EvaluationException ex)
+ {
+ log(Logger.LOG_ERROR, "FilterImpl: " + toString(), ex);
+ }
+ finally
+ {
+ if (dict != null)
+ {
+ mapper.setSource(null, caseSensitive);
+ }
+ else
+ {
+ mapper.setSource(null);
+ }
+
+ if (tuple == null)
+ {
+ m_cache.set(new SoftReference(new Object[] {evaluator, mapper}));
+ }
+ else
+ {
+ m_cache.set(tupleRef);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Filter using a <tt>Dictionary</tt> object. The <tt>Filter</tt>
+ * is executed using the <tt>Dictionary</tt> object's keys and values.
+ * @param dict the <tt>Dictionary</tt> object whose keys and values
+ * are used to determine a match.
+ * @return <tt>true</tt> if the <tt>Dictionary</tt> object's keys
+ * and values match this filter; <tt>false</tt> otherwise.
+ * @throws IllegalArgumentException if the dictionary contains case
+ * variants of the same key name.
+ **/
+ public boolean match(Dictionary dict)
+ throws IllegalArgumentException
+ {
+ return match(dict, null, false);
+ }
+
+ /**
+ * Filter using a service's properties. The <tt>Filter</tt>
+ * is executed using the properties of the referenced service.
+ * @param ref A reference to the service whose properties
+ * are used to determine a match.
+ * @return <tt>true</tt> if the service's properties match this
+ * filter; <tt>false</tt> otherwise.
+ **/
+ public boolean match(ServiceReference ref)
+ {
+ return match(null, ref, false);
+ }
+
+ public boolean matchCase(Dictionary dict)
+ {
+ return match(dict, null, true);
+ }
+
+ /**
+ * Returns the <tt>Filter</tt> object's filter string.
+ * @return Filter string.
+ **/
+ public String toString()
+ {
+ if (m_toString == null)
+ {
+ m_toString = new Evaluator(m_program).toStringInfix();
+ }
+ return m_toString;
+ }
+
+ private void log(int flag, String msg, Throwable th)
+ {
+ if (m_logger == null)
+ {
+ System.out.println(msg + ": " + th);
+ }
+ else
+ {
+ m_logger.log(flag, msg, th);
+ }
+ }
+
+ static class SimpleMapper implements Mapper
+ {
+ private ServiceReference m_ref = null;
+ private StringMap m_map = null;
+
+ public void setSource(ServiceReference ref)
+ {
+ m_ref = ref;
+ m_map = null;
+ }
+
+ public void setSource(Dictionary dict, boolean caseSensitive)
+ {
+ // Create a map if we don't have one.
+
+ if (m_map == null)
+ {
+ m_map = new StringMap();
+ }
+ else
+ {
+ m_map.clear();
+ }
+
+ // Set case comparison accordingly.
+ m_map.setCaseSensitive(caseSensitive);
+
+ // Put all dictionary entries into the map.
+ if (dict != null)
+ {
+ Enumeration keys = dict.keys();
+ while (keys.hasMoreElements())
+ {
+ Object key = keys.nextElement();
+ if (m_map.get(key) == null)
+ {
+ m_map.put(key, dict.get(key));
+ }
+ else
+ {
+ throw new IllegalArgumentException(
+ "Duplicate attribute: " + key.toString());
+ }
+ }
+ }
+ m_ref = null;
+ }
+
+ public Object lookup(String name)
+ {
+ if (m_map == null)
+ {
+ return m_ref.getProperty(name);
+ }
+ return m_map.get(name);
+ }
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,263 @@
+/*
+ * 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.framework;
+
+import java.util.*;
+
+class FindEntriesEnumeration implements Enumeration
+{
+ private FelixBundle m_bundle = null;
+ private Enumeration m_enumeration = null;
+ private String m_path = null;
+ private String[] m_filePattern = null;
+ private boolean m_recurse = false;
+ private Object m_next = null;
+
+ public FindEntriesEnumeration(
+ FelixBundle bundle, String path, String filePattern, boolean recurse)
+ {
+ m_bundle = bundle;
+ m_path = path;
+ m_enumeration = (m_bundle.getInfo().getCurrentModule().getContentLoader().getContent() == null)
+ ? null : m_bundle.getInfo().getCurrentModule().getContentLoader().getContent().getEntries();
+ m_recurse = recurse;
+
+ // Sanity check the parameters.
+ if (m_path == null)
+ {
+ throw new IllegalArgumentException("The path for findEntries() cannot be null.");
+ }
+ // Strip leading '/' if present.
+ if ((m_path.length() > 0) && (m_path.charAt(0) == '/'))
+ {
+ m_path = m_path.substring(1);
+ }
+ // Add a '/' to the end if not present.
+ if ((m_path.length() > 0) && (m_path.charAt(m_path.length() - 1) != '/'))
+ {
+ m_path = m_path + "/";
+ }
+
+ // File pattern defaults to "*" if not specified.
+ filePattern = (filePattern == null) ? "*" : filePattern;
+
+ m_filePattern = parseSubstring(filePattern);
+
+ m_next = findNext();
+ }
+
+ public boolean hasMoreElements()
+ {
+ return (m_next != null);
+ }
+
+ public Object nextElement()
+ {
+ if (m_next == null)
+ {
+ throw new NoSuchElementException("No more entry paths.");
+ }
+ Object last = m_next;
+ m_next = findNext();
+ return last;
+ }
+
+ private Object findNext()
+ {
+ // This method filters the content entry enumeration, such that
+ // it only displays the contents of the directory specified by
+ // the path argument either recursively or not; much like using
+ // "ls -R" or "ls" to list the contents of a directory, respectively.
+ while ((m_enumeration != null) && m_enumeration.hasMoreElements())
+ {
+ // Get the next entry name.
+ String entryName = (String) m_enumeration.nextElement();
+ // Check to see if it is a descendent of the specified path.
+ if (!entryName.equals(m_path) && entryName.startsWith(m_path))
+ {
+ // If this is recursive search, then try to match any
+ // entry path that starts with the specified path;
+ // otherwise, only try to match children of the specified
+ // path and not any grandchild. This code uses the knowledge
+ // that content entries corresponding to directories end in '/'.
+ int idx = entryName.indexOf('/', m_path.length());
+ if (m_recurse || (idx < 0) || (idx == (entryName.length() - 1)))
+ {
+ // Get the last element of the entry path, not including
+ // the '/' if it is a directory.
+ int endIdx = (entryName.charAt(entryName.length() - 1) == '/')
+ ? entryName.length() - 1
+ : entryName.length();
+ int startIdx = (entryName.charAt(entryName.length() - 1) == '/')
+ ? entryName.lastIndexOf('/', endIdx - 1) + 1
+ : entryName.lastIndexOf('/', endIdx) + 1;
+ String lastElement = entryName.substring(startIdx, endIdx);
+
+ // See if the file pattern matches the last element of the path.
+ if (checkSubstring(m_filePattern, lastElement))
+ {
+ // Convert entry name into an entry URL.
+ return m_bundle.getInfo().getCurrentModule()
+ .getContentLoader().getResourceFromContent(entryName);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //
+ // The following substring-related code was lifted and modified
+ // from the LDAP parser code.
+ //
+
+ private static String[] parseSubstring(String target)
+ {
+ List pieces = new ArrayList();
+ StringBuffer ss = new StringBuffer();
+ // int kind = SIMPLE; // assume until proven otherwise
+ boolean wasStar = false; // indicates last piece was a star
+ boolean leftstar = false; // track if the initial piece is a star
+ boolean rightstar = false; // track if the final piece is a star
+
+ int idx = 0;
+
+ // We assume (sub)strings can contain leading and trailing blanks
+ for (;;)
+ {
+ if (idx >= target.length())
+ {
+ if (wasStar)
+ {
+ // insert last piece as "" to handle trailing star
+ rightstar = true;
+ }
+ else
+ {
+ pieces.add(ss.toString());
+ // accumulate the last piece
+ // note that in the case of
+ // (cn=); this might be
+ // the string "" (!=null)
+ }
+ ss.setLength(0);
+ break;
+ }
+
+ char c = target.charAt(idx++);
+ if (c == '*')
+ {
+ if (wasStar)
+ {
+ // encountered two successive stars;
+ // I assume this is illegal
+ throw new IllegalArgumentException("Invalid filter string: " + target);
+ }
+ if (ss.length() > 0)
+ {
+ pieces.add(ss.toString()); // accumulate the pieces
+ // between '*' occurrences
+ }
+ ss.setLength(0);
+ // if this is a leading star, then track it
+ if (pieces.size() == 0)
+ {
+ leftstar = true;
+ }
+ ss.setLength(0);
+ wasStar = true;
+ }
+ else
+ {
+ wasStar = false;
+ ss.append(c);
+ }
+ }
+ if (leftstar || rightstar || pieces.size() > 1)
+ {
+ // insert leading and/or trailing "" to anchor ends
+ if (rightstar)
+ {
+ pieces.add("");
+ }
+ if (leftstar)
+ {
+ pieces.add(0, "");
+ }
+ }
+
+ return (String[]) pieces.toArray(new String[pieces.size()]);
+ }
+
+ private static boolean checkSubstring(String[] pieces, String s)
+ {
+ // Walk the pieces to match the string
+ // There are implicit stars between each piece,
+ // and the first and last pieces might be "" to anchor the match.
+ // assert (pieces.length > 1)
+ // minimal case is <string>*<string>
+
+ boolean result = false;
+ int len = pieces.length;
+ int index = 0;
+
+ for (int i = 0; i < len; i++)
+ {
+ String piece = (String) pieces[i];
+ if (i == len - 1)
+ {
+ // this is the last piece
+ if (s.endsWith(piece))
+ {
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ break;
+ }
+ // initial non-star; assert index == 0
+ else if (i == 0)
+ {
+ if (!s.startsWith(piece))
+ {
+ result = false;
+ break;
+ }
+ }
+ // assert i > 0 && i < len-1
+ else
+ {
+ // Sure wish stringbuffer supported e.g. indexOf
+ index = s.indexOf(piece, index);
+ if (index < 0)
+ {
+ result = false;
+ break;
+ }
+ }
+ // start beyond the matching piece
+ index += piece.length();
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,102 @@
+/*
+ * 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.framework;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+class GetEntryPathsEnumeration implements Enumeration
+{
+ private FelixBundle m_bundle = null;
+ private Enumeration m_enumeration = null;
+ private String m_path = null;
+ private Object m_next = null;
+
+ public GetEntryPathsEnumeration(FelixBundle bundle, String path)
+ {
+ m_bundle = bundle;
+ m_path = path;
+ m_enumeration = m_bundle.getInfo().getCurrentModule()
+ .getContentLoader().getContent().getEntries();
+
+ // Sanity check the parameters.
+ if (m_path == null)
+ {
+ throw new IllegalArgumentException("The path for findEntries() cannot be null.");
+ }
+ // Strip leading '/' if present.
+ if ((m_path.length() > 0) && (m_path.charAt(0) == '/'))
+ {
+ m_path = m_path.substring(1);
+ }
+ // Add a '/' to the end if not present.
+ if ((m_path.length() > 0) && (m_path.charAt(m_path.length() - 1) != '/'))
+ {
+ m_path = m_path + "/";
+ }
+
+ m_next = findNext();
+ }
+
+ public boolean hasMoreElements()
+ {
+ return (m_next != null);
+ }
+
+ public Object nextElement()
+ {
+ if (m_next == null)
+ {
+ throw new NoSuchElementException("No more entry paths.");
+ }
+ Object last = m_next;
+ m_next = findNext();
+ return last;
+ }
+
+ private Object findNext()
+ {
+ // This method filters the content entry enumeration, such that
+ // it only displays the contents of the directory specified by
+ // the path argument; much like using "ls" to list the contents
+ // of a directory.
+ while (m_enumeration.hasMoreElements())
+ {
+ // Get the next entry name.
+ String entryName = (String) m_enumeration.nextElement();
+ // Check to see if it is a descendent of the specified path.
+ if (!entryName.equals(m_path) && entryName.startsWith(m_path))
+ {
+ // Verify that it is a child of the path and not a
+ // grandchild by examining its remaining path length.
+ // This code uses the knowledge that content entries
+ // corresponding to directories end in '/'. It checks
+ // to see if the next occurrence of '/' is also the
+ // end of the string, which means that this entry
+ // represents a child directory of the path.
+ int idx = entryName.indexOf('/', m_path.length());
+ if ((idx < 0) || (idx == (entryName.length() - 1)))
+ {
+ return entryName;
+ }
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Logger.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Logger.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Logger.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Logger.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,299 @@
+/*
+ * 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.framework;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.osgi.framework.*;
+
+/**
+ * <p>
+ * This class mimics the standard OSGi <tt>LogService</tt> interface. An
+ * instance of this class is used by the framework for all logging. By default
+ * this class logs messages to standard out. The log level can be set to
+ * control the amount of logging performed, where a higher number results in
+ * more logging. A log level of zero turns off logging completely.
+ * </p>
+ * <p>
+ * The log levels match those specified in the OSGi Log Service (i.e., 1 = error,
+ * 2 = warning, 3 = information, and 4 = debug). The default value is 1.
+ * </p>
+ * <p>
+ * This class also uses the System Bundle's context to track log services
+ * and will use the highest ranking log service, if present, as a back end
+ * instead of printing to standard out. The class uses reflection to invoking
+ * the log service's method to avoid a dependency on the log interface.
+ * </p>
+**/
+public class Logger implements ServiceListener
+{
+ 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;
+
+ private int m_logLevel = 1;
+ private BundleContext m_context = null;
+
+ private final static int LOGGER_OBJECT_IDX = 0;
+ private final static int LOGGER_METHOD_IDX = 1;
+ private ServiceReference m_logRef = null;
+ private Object[] m_logger = null;
+
+ public Logger()
+ {
+ }
+
+ public final synchronized void setLogLevel(int i)
+ {
+ m_logLevel = i;
+ }
+
+ public final synchronized int getLogLevel()
+ {
+ return m_logLevel;
+ }
+
+ protected void setSystemBundleContext(BundleContext context)
+ {
+ // TODO: Find a way to log to a log service inside the framework.
+ // The issue is that we log messages while holding framework
+ // internal locks -- hence, when a log service calls back into
+ // the framework (e.g., by loading a class) we might deadlock.
+ // One instance of this problem is tracked in FELIX-536.
+ // For now we just disable logging to log services inside the
+ // framework.
+
+ // m_context = context;
+ // startListeningForLogService();
+ }
+
+ public final void log(int level, String msg)
+ {
+ _log(null, level, msg, null);
+ }
+
+ public final void log(int level, String msg, Throwable throwable)
+ {
+ _log(null, level, msg, throwable);
+ }
+
+ public final void log(ServiceReference sr, int level, String msg)
+ {
+ _log(sr, level, msg, null);
+ }
+
+ public final void log(ServiceReference sr, int level, String msg, Throwable throwable)
+ {
+ _log(sr, level, msg, throwable);
+ }
+
+ protected void doLog(ServiceReference sr, int level, String msg, Throwable throwable)
+ {
+ String s = (sr == null) ? null : "SvcRef " + sr;
+ s = (s == null) ? msg : s + " " + msg;
+ s = (throwable == null) ? s : s + " (" + throwable + ")";
+ switch (level)
+ {
+ case LOG_DEBUG:
+ System.out.println("DEBUG: " + s);
+ break;
+ case LOG_ERROR:
+ System.out.println("ERROR: " + s);
+ if (throwable != null)
+ {
+ if ((throwable instanceof BundleException) &&
+ (((BundleException) throwable).getNestedException() != null))
+ {
+ throwable = ((BundleException) throwable).getNestedException();
+ }
+ throwable.printStackTrace();
+ }
+ break;
+ case LOG_INFO:
+ System.out.println("INFO: " + s);
+ break;
+ case LOG_WARNING:
+ System.out.println("WARNING: " + s);
+ break;
+ default:
+ System.out.println("UNKNOWN[" + level + "]: " + s);
+ }
+ }
+
+ private void _log(ServiceReference sr, int level, String msg, Throwable throwable)
+ {
+ // Save our own copy just in case it changes. We could try to do
+ // more conservative locking here, but let's be optimistic.
+ Object[] logger = m_logger;
+
+ if (m_logLevel >= level)
+ {
+ // Use the log service if available.
+ if (logger != null)
+ {
+ _logReflectively(logger, sr, level, msg, throwable);
+ }
+ // Otherwise, default logging action.
+ else
+ {
+ doLog(sr, level, msg, throwable);
+ }
+ }
+ }
+
+ private void _logReflectively(
+ Object[] logger, ServiceReference sr, int level, String msg, Throwable throwable)
+ {
+ if (logger != null)
+ {
+ Object[] params = {
+ sr, new Integer(level), msg, throwable
+ };
+ try
+ {
+ ((Method) logger[LOGGER_METHOD_IDX]).invoke(logger[LOGGER_OBJECT_IDX], params);
+ }
+ catch (InvocationTargetException ex)
+ {
+ System.err.println("Logger: " + ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ System.err.println("Logger: " + ex);
+ }
+ }
+ }
+
+ /**
+ * This method is called when the system bundle context is set;
+ * it simply adds a service listener so that the system bundle can track
+ * log services to be used as the back end of the logging mechanism. It also
+ * attempts to get an existing log service, if present, but in general
+ * there will never be a log service present since the system bundle is
+ * started before every other bundle.
+ **/
+ private synchronized void startListeningForLogService()
+ {
+ // Add a service listener for log services.
+ try
+ {
+ m_context.addServiceListener(
+ this, "(objectClass=org.osgi.service.log.LogService)");
+ }
+ catch (InvalidSyntaxException ex) {
+ // This will never happen since the filter is hard coded.
+ }
+ // Try to get an existing log service.
+ m_logRef = m_context.getServiceReference("org.osgi.service.log.LogService");
+ // Get the service object if available and set it in the logger.
+ if (m_logRef != null)
+ {
+ setLogger(m_context.getService(m_logRef));
+ }
+ }
+
+ /**
+ * This method implements the callback for the ServiceListener interface.
+ * It is public as a byproduct of implementing the interface and should
+ * not be called directly. This method tracks run-time changes to log
+ * service availability. If the log service being used by the framework's
+ * logging mechanism goes away, then this will try to find an alternative.
+ * If a higher ranking log service is registered, then this will switch
+ * to the higher ranking log service.
+ **/
+ public final synchronized void serviceChanged(ServiceEvent event)
+ {
+ // If no logger is in use, then grab this one.
+ if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef == null))
+ {
+ m_logRef = event.getServiceReference();
+ // Get the service object and set it in the logger.
+ setLogger(m_context.getService(m_logRef));
+ }
+ // If a logger is in use, but this one has a higher ranking, then swap
+ // it for the existing logger.
+ else if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef != null))
+ {
+ ServiceReference ref =
+ m_context.getServiceReference("org.osgi.service.log.LogService");
+ if (!ref.equals(m_logRef))
+ {
+ m_context.ungetService(m_logRef);
+ m_logRef = ref;
+ setLogger(m_context.getService(m_logRef));
+ }
+
+ }
+ // If the current logger is going away, release it and try to
+ // find another one.
+ else if ((event.getType() == ServiceEvent.UNREGISTERING) &&
+ m_logRef.equals(event.getServiceReference()))
+ {
+ // Unget the service object.
+ m_context.ungetService(m_logRef);
+ // Try to get an existing log service.
+ m_logRef = m_context.getServiceReference(
+ "org.osgi.service.log.LogService");
+ // Get the service object if available and set it in the logger.
+ if (m_logRef != null)
+ {
+ setLogger(m_context.getService(m_logRef));
+ }
+ else
+ {
+ setLogger(null);
+ }
+ }
+ }
+
+ /**
+ * This method sets the new log service object. It also caches the method to
+ * invoke. The service object and method are stored in array to optimistically
+ * eliminate the need to locking when logging.
+ **/
+ private void setLogger(Object logObj)
+ {
+ if (logObj == null)
+ {
+ m_logger = null;
+ }
+ else
+ {
+ Class[] formalParams = {
+ ServiceReference.class,
+ Integer.TYPE,
+ String.class,
+ Throwable.class
+ };
+
+ try
+ {
+ Method logMethod = logObj.getClass().getMethod("log", formalParams);
+ logMethod.setAccessible(true);
+ m_logger = new Object[] { logObj, logMethod };
+ }
+ catch (NoSuchMethodException ex)
+ {
+ System.err.println("Logger: " + ex);
+ m_logger = null;
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Logger.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/Logger.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,47 @@
+/*
+ * 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.framework;
+
+import org.osgi.framework.*;
+
+class PackageAdminActivator implements BundleActivator
+{
+ private Felix m_felix = null;
+ private ServiceRegistration m_reg = null;
+ private PackageAdminImpl m_packageAdmin = null;
+
+ public PackageAdminActivator(Felix felix)
+ {
+ m_felix = felix;
+ }
+
+ public void start(BundleContext context) throws Exception
+ {
+ m_packageAdmin = new PackageAdminImpl(m_felix);
+ m_reg = context.registerService(
+ org.osgi.service.packageadmin.PackageAdmin.class.getName(),
+ m_packageAdmin, null);
+ }
+
+ public void stop(BundleContext context) throws Exception
+ {
+ m_reg.unregister();
+ m_packageAdmin.stop();
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,309 @@
+/*
+ * 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.framework;
+
+import java.util.*;
+
+import org.apache.felix.framework.util.VersionRange;
+import org.osgi.framework.*;
+import org.osgi.service.packageadmin.*;
+
+class PackageAdminImpl implements PackageAdmin, Runnable
+{
+ private static final Comparator COMPARATOR = new Comparator() {
+ public int compare(Object o1, Object o2)
+ {
+ // Reverse arguments to sort in descending order.
+ return ((ExportedPackage) o2).getVersion().compareTo(
+ ((ExportedPackage) o1).getVersion());
+ }
+ };
+
+ private Felix m_felix = null;
+ private Bundle[][] m_reqBundles = null;
+ private Bundle m_systemBundle = null;
+ private Thread m_thread = null;
+
+ public PackageAdminImpl(Felix felix)
+ {
+ m_felix = felix;
+ m_systemBundle = m_felix.getBundle(0);
+
+ // Start a thread to perform asynchronous package refreshes.
+ m_thread = new Thread(this, "FelixPackageAdmin");
+ m_thread.setDaemon(true);
+ m_thread.start();
+ }
+
+ /**
+ * Stops the FelixPackageAdmin thread on system shutdown. Shutting down the
+ * thread explicitly is required in the embedded case, where Felix may be
+ * stopped without the Java VM being stopped. In this case the
+ * FelixPackageAdmin thread must be stopped explicitly.
+ * <p>
+ * This method is called by the
+ * {@link PackageAdminActivator#stop(BundleContext)} method.
+ */
+ synchronized void stop()
+ {
+ if (m_thread != null)
+ {
+ // Null thread variable to signal to the thread that
+ // we want it to exit.
+ m_thread = null;
+
+ // Wake up the thread, if it is currently in the wait() state
+ // for more work.
+ notifyAll();
+ }
+ }
+
+ /**
+ * Returns the bundle associated with this class if the class was
+ * loaded from a bundle, otherwise returns null.
+ *
+ * @param clazz the class for which to determine its associated bundle.
+ * @return the bundle associated with the specified class, otherwise null.
+ **/
+ public Bundle getBundle(Class clazz)
+ {
+ return m_felix.getBundle(clazz);
+ }
+
+ /**
+ * Returns all bundles that have a specified symbolic name and whose
+ * version is in the specified version range. If no version range is
+ * specified, then all bundles with the specified symbolic name are
+ * returned. The array is sorted in descending version order.
+ *
+ * @param symbolicName the target symbolic name.
+ * @param versionRange the target version range.
+ * @return an array of matching bundles sorted in descending version order.
+ **/
+ public Bundle[] getBundles(String symbolicName, String versionRange)
+ {
+// TODO: PACKAGEADMIN - This could be made more efficient by reducing object creation.
+ VersionRange vr = (versionRange == null)
+ ? null : VersionRange.parse(versionRange);
+ Bundle[] bundles = m_felix.getBundles();
+ List list = new ArrayList();
+ for (int i = 0; (bundles != null) && (i < bundles.length); i++)
+ {
+ String sym = (String) ((FelixBundle) bundles[i])
+ .getInfo().getCurrentHeader().get(Constants.BUNDLE_SYMBOLICNAME);
+ if ((sym != null) && sym.equals(symbolicName))
+ {
+ String s = (String) ((FelixBundle) bundles[i])
+ .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+ Version v = (s == null) ? new Version("0.0.0") : new Version(s);
+ if ((vr == null) || vr.isInRange(v))
+ {
+ list.add(bundles[i]);
+ }
+ }
+ }
+ if (list.size() == 0)
+ {
+ return null;
+ }
+ bundles = (Bundle[]) list.toArray(new Bundle[list.size()]);
+ Arrays.sort(bundles,new Comparator() {
+ public int compare(Object o1, Object o2)
+ {
+ String s1 = (String) ((FelixBundle) o1)
+ .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+ String s2 = (String) ((FelixBundle) o2)
+ .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+ Version v1 = (s1 == null) ? new Version("0.0.0") : new Version(s1);
+ Version v2 = (s2 == null) ? new Version("0.0.0") : new Version(s2);
+ // Compare in reverse order to get descending sort.
+ return v2.compareTo(v1);
+ }
+ });
+ return bundles;
+ }
+
+ public int getBundleType(Bundle bundle)
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the exported package associated with the specified
+ * package name. If there are more than one version of the package
+ * being exported, then the highest version is returned.
+ *
+ * @param name the name of the exported package to find.
+ * @return the exported package or null if no matching package was found.
+ **/
+ public ExportedPackage getExportedPackage(String name)
+ {
+ // Get all versions of the exported package.
+ ExportedPackage[] pkgs = m_felix.getExportedPackages(name);
+ // If there are no versions exported, then return null.
+ if ((pkgs == null) || (pkgs.length == 0))
+ {
+ return null;
+ }
+ // Sort the exported versions.
+ Arrays.sort(pkgs, COMPARATOR);
+ // Return the highest version.
+ return pkgs[0];
+ }
+
+ public ExportedPackage[] getExportedPackages(String name)
+ {
+ ExportedPackage[] pkgs = m_felix.getExportedPackages(name);
+ return ((pkgs == null) || pkgs.length == 0) ? null : pkgs;
+ }
+
+ /**
+ * Returns the packages exported by the specified bundle.
+ *
+ * @param bundle the bundle whose exported packages are to be returned.
+ * @return an array of packages exported by the bundle or null if the
+ * bundle does not export any packages.
+ **/
+ public ExportedPackage[] getExportedPackages(Bundle bundle)
+ {
+ return m_felix.getExportedPackages(bundle);
+ }
+
+ /**
+ * The OSGi specification states that refreshing packages is
+ * asynchronous; this method simply notifies the package admin
+ * thread to do a refresh.
+ * @param bundles array of bundles to refresh or <tt>null</tt> to refresh
+ * any bundles in need of refreshing.
+ **/
+ public synchronized void refreshPackages(Bundle[] bundles)
+ throws SecurityException
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(m_systemBundle, AdminPermission.RESOLVE));
+ }
+
+ // Save our request parameters and notify all.
+ if (m_reqBundles == null)
+ {
+ m_reqBundles = new Bundle[][] { bundles };
+ }
+ else
+ {
+ Bundle[][] newReqBundles = new Bundle[m_reqBundles.length + 1][];
+ System.arraycopy(m_reqBundles, 0,
+ newReqBundles, 0, m_reqBundles.length);
+ newReqBundles[m_reqBundles.length] = bundles;
+ m_reqBundles = newReqBundles;
+ }
+ notifyAll();
+ }
+
+ /**
+ * The OSGi specification states that package refreshes happen
+ * asynchronously; this is the run() method for the package
+ * refreshing thread.
+ **/
+ public void run()
+ {
+ // This thread loops forever, thus it should
+ // be a daemon thread.
+ Bundle[] bundles = null;
+ while (true)
+ {
+ synchronized (this)
+ {
+ // Wait for a refresh request.
+ while (m_reqBundles == null)
+ {
+ // Terminate the thread if requested to do so (see stop()).
+ if (m_thread == null)
+ {
+ return;
+ }
+
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ex)
+ {
+ }
+ }
+
+ // Get the bundles parameter for the current refresh request.
+ bundles = m_reqBundles[0];
+ }
+
+ // Perform refresh.
+ m_felix.refreshPackages(bundles);
+
+ // Remove the first request since it is now completed.
+ synchronized (this)
+ {
+ if (m_reqBundles.length == 1)
+ {
+ m_reqBundles = null;
+ }
+ else
+ {
+ Bundle[][] newReqBundles = new Bundle[m_reqBundles.length - 1][];
+ System.arraycopy(m_reqBundles, 1,
+ newReqBundles, 0, m_reqBundles.length - 1);
+ m_reqBundles = newReqBundles;
+ }
+ }
+ }
+ }
+
+ public boolean resolveBundles(Bundle[] bundles)
+ {
+ Object sm = System.getSecurityManager();
+
+ if (sm != null)
+ {
+ ((SecurityManager) sm).checkPermission(
+ new AdminPermission(m_systemBundle, AdminPermission.RESOLVE));
+ }
+
+ return m_felix.resolveBundles(bundles);
+ }
+
+ public RequiredBundle[] getRequiredBundles(String symbolicName)
+ {
+ // TODO: Implement PackageAdmin.getRequiredBundles()
+ return null;
+ }
+
+ public Bundle[] getFragments(Bundle bundle)
+ {
+ // TODO: Implement PackageAdmin.getFragments()
+ return null;
+ }
+
+ public Bundle[] getHosts(Bundle bundle)
+ {
+ // TODO: Implement PackageAdmin.getHosts()
+ return null;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,195 @@
+/*
+ * 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.framework;
+
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.moduleloader.IModule;
+import org.apache.felix.moduleloader.IWire;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+class ServiceReferenceImpl implements ServiceReference
+{
+ private ServiceRegistrationImpl m_registration = null;
+ private Bundle m_bundle = null;
+
+ public ServiceReferenceImpl(ServiceRegistrationImpl reg, Bundle bundle)
+ {
+ m_registration = reg;
+ m_bundle = bundle;
+ }
+
+ protected ServiceRegistrationImpl getServiceRegistration()
+ {
+ return m_registration;
+ }
+
+ public Object getProperty(String s)
+ {
+ return m_registration.getProperty(s);
+ }
+
+ public String[] getPropertyKeys()
+ {
+ return m_registration.getPropertyKeys();
+ }
+
+ public Bundle getBundle()
+ {
+ // The spec says that this should return null if
+ // the service is unregistered.
+ return (m_registration.isValid()) ? m_bundle : null;
+ }
+
+ public Bundle[] getUsingBundles()
+ {
+ return m_registration.getUsingBundles();
+ }
+
+ public boolean equals(Object obj)
+ {
+ try
+ {
+ ServiceReferenceImpl ref = (ServiceReferenceImpl) obj;
+ return ref.m_registration == m_registration;
+ }
+ catch (ClassCastException ex)
+ {
+ // Ignore and return false.
+ }
+ catch (NullPointerException ex)
+ {
+ // Ignore and return false.
+ }
+
+ return false;
+ }
+
+ public int hashCode()
+ {
+ if (m_registration.getReference() != null)
+ {
+ if (m_registration.getReference() != this)
+ {
+ return m_registration.getReference().hashCode();
+ }
+ return super.hashCode();
+ }
+ return 0;
+ }
+
+ public String toString()
+ {
+ String[] ocs = (String[]) getProperty("objectClass");
+ String oc = "[";
+ for(int i = 0; i < ocs.length; i++)
+ {
+ oc = oc + ocs[i];
+ if (i < ocs.length - 1)
+ oc = oc + ", ";
+ }
+ oc = oc + "]";
+ return oc;
+ }
+
+ public boolean isAssignableTo(Bundle requester, String className)
+ {
+ // Always return true if the requester is the same as the provider.
+ if (requester == m_bundle)
+ {
+ return true;
+ }
+
+ // Boolean flag.
+ boolean allow = true;
+ // Get the package.
+ String pkgName =
+ Util.getClassPackage(className);
+ IModule requesterModule =
+ ((FelixBundle) requester).getInfo().getCurrentModule();
+ // Get package wiring from service requester.
+ IWire requesterWire = Util.getWire(requesterModule, pkgName);
+
+ // There are three situations that may occur here:
+ // 1. The requester does not have a wire for the package.
+ // 2. The provider does not have a wire for the package.
+ // 3. Both have a wire for the package.
+ // For case 1, we do not filter the service reference since we
+ // assume that the bundle is using reflection or that it won't
+ // use that class at all since it does not import it. For
+ // case 2, we have to try to load the class from the class
+ // loader of the service object and then compare the class
+ // loaders to determine if we should filter the service
+ // refernce. In case 3, we simply compare the exporting
+ // modules from the package wiring to determine if we need
+ // to filter the service reference.
+
+ // Case 1: Always include service reference.
+ if (requesterWire == null)
+ {
+ return allow;
+ }
+
+ // Get package wiring from service provider.
+ IModule providerModule =
+ ((FelixBundle) m_bundle).getInfo().getCurrentModule();
+ IWire providerWire = Util.getWire(providerModule, pkgName);
+
+ // Case 2: Only include service reference if the service
+ // object uses the same class as the requester.
+ if (providerWire == null)
+ {
+ // If the provider is not the exporter of the requester's package,
+ // then try to use the service registration to see if the requester's
+ // class is accessible.
+ if (!((FelixBundle) m_bundle).getInfo().hasModule(requesterWire.getExporter()))
+ {
+ try
+ {
+ // Load the class from the requesting bundle.
+ Class requestClass = requesterModule.getClass(className);
+ // Get the service registration and ask it to check
+ // if the service object is assignable to the requesting
+ // bundle's class.
+ allow = getServiceRegistration().isClassAccessible(requestClass);
+ }
+ catch (Exception ex)
+ {
+ // This should not happen, filter to be safe.
+ allow = false;
+ }
+ }
+ else
+ {
+ // O.k. the provider is the exporter of the requester's package, now check
+ // if the requester is wired to the latest version of the provider, if so
+ // then allow else don't (the provider has been updated but not refreshed).
+ allow = providerModule == requesterWire.getExporter();
+ }
+ }
+ // Case 3: Include service reference if the wires have the
+ // same source module.
+ else
+ {
+ allow = providerWire.getExporter().equals(requesterWire.getExporter());
+ }
+
+ return allow;
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java Mon Sep 1 08:08:01 2008
@@ -0,0 +1,322 @@
+/*
+ * 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.framework;
+
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.felix.framework.util.StringMap;
+import org.apache.felix.framework.util.Util;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+class ServiceRegistrationImpl implements ServiceRegistration
+{
+ // Service registry.
+ private ServiceRegistry m_registry = null;
+ // Bundle implementing the service.
+ private Bundle m_bundle = null;
+ // Interfaces associated with the service object.
+ private String[] m_classes = null;
+ // Service Id associated with the service object.
+ private Long m_serviceId = null;
+ // Service object.
+ private Object m_svcObj = null;
+ // Service factory interface.
+ private ServiceFactory m_factory = null;
+ // Associated property dictionary.
+ private Map m_propMap = new StringMap(false);
+ // Re-usable service reference.
+ private ServiceReferenceImpl m_ref = null;
+ // Flag indicating that we are unregistering.
+ private boolean m_isUnregistering = false;
+
+ public ServiceRegistrationImpl(
+ ServiceRegistry registry, Bundle bundle,
+ String[] classes, Long serviceId,
+ Object svcObj, Dictionary dict)
+ {
+ m_registry = registry;
+ m_bundle = bundle;
+ m_classes = classes;
+ m_serviceId = serviceId;
+ m_svcObj = svcObj;
+ m_factory = (m_svcObj instanceof ServiceFactory)
+ ? (ServiceFactory) m_svcObj : null;
+
+ initializeProperties(dict);
+
+ // This reference is the "standard" reference for this
+ // service and will always be returned by getReference().
+ // Since all reference to this service are supposed to
+ // be equal, we use the hashcode of this reference for
+ // a references to this service in ServiceReference.
+ m_ref = new ServiceReferenceImpl(this, m_bundle);
+
+ }
+
+ protected synchronized boolean isValid()
+ {
+ return (m_svcObj != null);
+ }
+
+ protected synchronized void invalidate()
+ {
+ m_svcObj = null;
+ }
+
+ public ServiceReference getReference()
+ {
+ return m_ref;
+ }
+
+ public void setProperties(Dictionary dict)
+ {
+ // Make sure registration is valid.
+ if (!isValid())
+ {
+ throw new IllegalStateException(
+ "The service registration is no longer valid.");
+ }
+ // Set the properties.
+ initializeProperties(dict);
+
+ // Tell registry about it.
+ m_registry.servicePropertiesModified(this);
+ }
+
+ public void unregister()
+ {
+ synchronized (this)
+ {
+ if (!isValid() || m_isUnregistering)
+ {
+ throw new IllegalStateException("Service already unregistered.");
+ }
+ m_isUnregistering = true;
+ }
+
+ removeHook();
+ m_registry.unregisterService(m_bundle, this);
+
+ synchronized (this)
+ {
+ m_svcObj = null;
+ m_factory = null;
+ }
+ }
+
+ private void removeHook() {
+ m_registry.removeHook(m_svcObj);
+ }
+
+ //
+ // Utility methods.
+ //
+
+ /**
+ * This method determines if the class loader of the service object
+ * has access to the specified class.
+ * @param clazz the class to test for reachability.
+ * @return <tt>true</tt> if the specified class is reachable from the
+ * service object's class loader, <tt>false</tt> otherwise.
+ **/
+ protected boolean isClassAccessible(Class clazz)
+ {
+ try
+ {
+ // Try to load from the service object or service factory class.
+ Class sourceClass = (m_factory != null)
+ ? m_factory.getClass() : m_svcObj.getClass();
+ Class targetClass = Util.loadClassUsingClass(sourceClass, clazz.getName());
+ return (targetClass == clazz);
+ }
+ catch (Exception ex)
+ {
+ // Ignore this and return false.
+ }
+ return false;
+ }
+
+ protected Object getProperty(String key)
+ {
+ return m_propMap.get(key);
+ }
+
+ private transient ArrayList m_list = new ArrayList();
+
+ protected String[] getPropertyKeys()
+ {
+ synchronized (m_propMap)
+ {
+ m_list.clear();
+ Iterator i = m_propMap.entrySet().iterator();
+ while (i.hasNext())
+ {
+ Map.Entry entry = (Map.Entry) i.next();
+ m_list.add(entry.getKey());
+ }
+ return (String[]) m_list.toArray(new String[m_list.size()]);
+ }
+ }
+
+ protected Bundle[] getUsingBundles()
+ {
+ return m_registry.getUsingBundles(m_ref);
+ }
+
+ protected Object getService(Bundle acqBundle)
+ {
+ // If the service object is a service factory, then
+ // let it create the service object.
+ if (m_factory != null)
+ {
+ try
+ {
+ if (System.getSecurityManager() != null)
+ {
+ return AccessController.doPrivileged(
+ new ServiceFactoryPrivileged(acqBundle, null));
+ }
+ else
+ {
+ return getFactoryUnchecked(acqBundle);
+ }
+ }
+ catch (Exception ex)
+ {
+ m_registry.getLogger().log(
+ Logger.LOG_ERROR, "ServiceRegistrationImpl: Error getting service.", ex);
+ return null;
+ }
+ }
+ else
+ {
+ return m_svcObj;
+ }
+ }
+
+ protected void ungetService(Bundle relBundle, Object svcObj)
+ {
+ // If the service object is a service factory, then
+ // let it release the service object.
+ if (m_factory != null)
+ {
+ try
+ {
+ if (System.getSecurityManager() != null)
+ {
+ AccessController.doPrivileged(
+ new ServiceFactoryPrivileged(relBundle, svcObj));
+ }
+ else
+ {
+ ungetFactoryUnchecked(relBundle, svcObj);
+ }
+ }
+ catch (Exception ex)
+ {
+ m_registry.getLogger().log(
+ Logger.LOG_ERROR, "ServiceRegistrationImpl: Error ungetting service.", ex);
+ }
+ }
+ }
+
+ private void initializeProperties(Dictionary dict)
+ {
+ synchronized (m_propMap)
+ {
+ m_propMap.clear();
+
+ if (dict != null)
+ {
+ Enumeration keys = dict.keys();
+ while (keys.hasMoreElements())
+ {
+ Object key = keys.nextElement();
+ m_propMap.put(key, dict.get(key));
+ }
+ }
+
+ // Add the framework assigned properties.
+ m_propMap.put(Constants.OBJECTCLASS, m_classes);
+ m_propMap.put(Constants.SERVICE_ID, m_serviceId);
+ }
+ }
+
+ private Object getFactoryUnchecked(Bundle bundle)
+ {
+ Object svcObj = m_factory.getService(bundle, this);
+ if (svcObj != null)
+ {
+ for (int i = 0; i < m_classes.length; i++)
+ {
+ Class clazz = Util.loadClassUsingClass(svcObj.getClass(), m_classes[i]);
+ if ((clazz == null) || !clazz.isAssignableFrom(svcObj.getClass()))
+ {
+ return null;
+ }
+ }
+ }
+ return svcObj;
+ }
+
+ private void ungetFactoryUnchecked(Bundle bundle, Object svcObj)
+ {
+ m_factory.ungetService(bundle, this, svcObj);
+ }
+
+ /**
+ * This simple class is used to ensure that when a service factory
+ * is called, that no other classes on the call stack interferes
+ * with the permissions of the factory itself.
+ **/
+ private class ServiceFactoryPrivileged implements PrivilegedExceptionAction
+ {
+ private Bundle m_bundle = null;
+ private Object m_svcObj = null;
+
+ public ServiceFactoryPrivileged(Bundle bundle, Object svcObj)
+ {
+ m_bundle = bundle;
+ m_svcObj = svcObj;
+ }
+
+ public Object run() throws Exception
+ {
+ if (m_svcObj == null)
+ {
+ return getFactoryUnchecked(m_bundle);
+ }
+ else
+ {
+ ungetFactoryUnchecked(m_bundle, m_svcObj);
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
------------------------------------------------------------------------------
svn:keywords = Rev Date