You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/12/07 20:32:33 UTC

svn commit: r888101 [2/2] - in /felix/trunk: ./ useradmin/ useradmin/src/ useradmin/src/main/ useradmin/src/main/java/ useradmin/src/main/java/org/ useradmin/src/main/java/org/apache/ useradmin/src/main/java/org/apache/felix/ useradmin/src/main/java/or...

Added: felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminEventDipatcherImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminEventDipatcherImpl.java?rev=888101&view=auto
==============================================================================
--- felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminEventDipatcherImpl.java (added)
+++ felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminEventDipatcherImpl.java Mon Dec  7 19:32:28 2009
@@ -0,0 +1,218 @@
+/**
+ *  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.useradmin.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.felix.useradmin.UserAdminEventDispatcher;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.useradmin.UserAdminEvent;
+import org.osgi.service.useradmin.UserAdminListener;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Dispatching UserAdmin events.
+ * @see org.apache.felix.useradmin.UserAdminEventDispatcher
+ * 
+ * @version $Rev$ $Date$
+ */
+public class UserAdminEventDipatcherImpl extends Thread implements UserAdminEventDispatcher
+{
+    private Vector queue;
+    private ServiceTracker userAdminTrackerListener;
+    private ServiceTracker eventAdminTracker;
+    private static final String userAdminTopic = "org/osgi/service/useradmin/UserAdmin/";
+    private volatile boolean running;
+
+    /**
+     * This constructor is used to create UserAdmin event dispatcher.
+     * It creating and opening two trackers for UserAdminListener and EventAdmin service.
+     * Setting thread as a daemon.
+     * @param context bundle context
+     */
+    public UserAdminEventDipatcherImpl(BundleContext context)
+    {
+        super();
+        this.queue = new Vector();
+        this.userAdminTrackerListener = new ServiceTracker(context, UserAdminListener.class.getName(), null);
+        this.userAdminTrackerListener.open();
+        this.eventAdminTracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
+        this.eventAdminTracker.open();
+        this.running = true;
+        setDaemon(true);
+        setName("UserAdminEventDispatcher-Thread");
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.impl.UserAdminEventDispatcher#start()
+     */
+    public void start()
+    {
+        super.start();
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.impl.UserAdminEventDispatcher#run()
+     */
+    public void run()
+    {
+        while (running)
+        {
+            UserAdminEvent event = take();
+            if (event != null)
+            {
+                notifyListeners(event);
+            }
+
+        }
+    }
+
+    /**
+     * Notifying UserAdminListeners about change made to roles.
+     * 
+     * @param event @see org.osgi.service.useradmin.UserAdminEvent
+     */
+    private void notifyListeners(UserAdminEvent event)
+    {
+        Object[] services = userAdminTrackerListener.getServices();
+        if (services != null)
+        {
+            for (int i = 0; i < services.length; i++)
+            {
+                UserAdminListener listener = ((UserAdminListener) services[i]);
+                listener.roleChanged(event);
+            }
+        }
+    }
+
+    /**
+     * @see
+     * org.apache.felix.useradmin.impl.UserAdminEventDispatcher#dispatchEventAsynchronusly(org.osgi.service.useradmin
+     * .UserAdminEvent)
+     */
+    public synchronized void dispatchEventAsynchronusly(UserAdminEvent userAdminEvent)
+    {
+        EventAdmin eventAdmin = (EventAdmin) eventAdminTracker.getService();
+        if (eventAdmin != null)
+        {
+            Event event = createEvent(userAdminEvent);
+            eventAdmin.postEvent(event);
+        }
+        queue.add(userAdminEvent);
+        notifyAll();
+    }
+
+    /**
+     * This method is consuming event from the queue if queue is empty and dispatcher is running
+     * waiting for events. 
+     * @return UserAdmin event
+     */
+    private synchronized UserAdminEvent take()
+    {
+
+        while (running && queue.isEmpty())
+        {
+            try
+            {
+                wait();
+            }
+            catch (InterruptedException e)
+            {
+            }
+        }
+
+        if (running)
+        {
+            UserAdminEvent event = (UserAdminEvent) queue.get(0);
+            queue.removeElementAt(0);
+            return event;
+        }
+        else
+        {
+            return null;
+        }
+
+    }
+
+    /**
+     * Closing UserAdminTrackers and putting running state to false.
+     * @see org.apache.felix.useradmin.impl.UserAdminEventDispatcher#close()
+     */
+    public void close()
+    {
+        userAdminTrackerListener.close();
+        running = true;
+    }
+
+    /**
+     * This method is creating OSGi event from UserAdminEvent.
+     * @param userAdminEvent event.
+     * @return OSGi event converted from UserAdmin event.
+     */
+    private Event createEvent(UserAdminEvent userAdminEvent)
+    {
+        String topic = getEventAdminTopic(userAdminEvent.getType());
+        Dictionary eventProperties = new Hashtable();
+
+        eventProperties.put(EventConstants.EVENT_TOPIC, topic);
+        eventProperties.put(EventConstants.EVENT, userAdminEvent);
+        eventProperties.put(EventConstants.TIMESTAMP, new Long(System.currentTimeMillis()));
+        eventProperties.put("role", userAdminEvent.getRole());
+        eventProperties.put("role.name", userAdminEvent.getRole().getName());
+        eventProperties.put("role.type", new Integer(userAdminEvent.getRole().getType()));
+        eventProperties.put(EventConstants.SERVICE, userAdminEvent.getServiceReference());
+        eventProperties.put(EventConstants.SERVICE_ID, userAdminEvent.getServiceReference().getProperty(
+            Constants.SERVICE_ID));
+        eventProperties.put(EventConstants.SERVICE_OBJECTCLASS, userAdminEvent.getServiceReference().getProperty(
+            Constants.OBJECTCLASS));
+        eventProperties.put(EventConstants.SERVICE_PID, userAdminEvent.getServiceReference().getProperty(
+            Constants.SERVICE_PID));
+
+        return new Event(topic, eventProperties);
+
+    }
+
+    /**
+     * This method is getting topic for specific event type. 
+     * @param type role type.
+     * @return OSGi topic specific for UserAdminEvent.
+     */
+    private String getEventAdminTopic(int type)
+    {
+        String evtType = "?";
+
+        switch (type)
+        {
+            case UserAdminEvent.ROLE_CREATED:
+                evtType = "ROLE_CREATED";
+                break;
+            case UserAdminEvent.ROLE_CHANGED:
+                evtType = "ROLE_CHANGED";
+                break;
+            case UserAdminEvent.ROLE_REMOVED:
+                evtType = "ROLE_REMOVED";
+                break;
+        }
+        return userAdminTopic + evtType;
+    }
+}

Added: felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryImpl.java?rev=888101&view=auto
==============================================================================
--- felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryImpl.java (added)
+++ felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryImpl.java Mon Dec  7 19:32:28 2009
@@ -0,0 +1,150 @@
+/**
+ *  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.useradmin.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Hashtable;
+
+import org.apache.felix.useradmin.UserAdminRepository;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+/**
+ * UserAdminRepository implementation of {@link UserAdminRepository}.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class UserAdminRepositoryImpl implements UserAdminRepository
+{
+    /**
+     * UserAdmin repository cache, caching all roles during runtime.
+     */
+    private Hashtable repositoryCache;
+    /**
+     * Store file name.
+     */
+    private String repositoryFileName;
+    /**
+     * Store file.
+     */
+    private File repositoryFile;
+    /**
+     * Property pointing out the file containing the role database information.
+     */
+    private final static String DBPROP = "org.apache.felix.useradmin.db";
+    private Logger logger;
+
+    /**
+     * Constructs new UserAdminRepository.
+     * @param logger Logger instance.
+     * @param context bundle context.
+     */
+    public UserAdminRepositoryImpl(Logger logger, BundleContext context)
+    {
+        this.repositoryFileName = System.getProperty(DBPROP, "useradmin.db");
+        this.logger = logger;
+        this.repositoryFile = context.getDataFile(repositoryFileName);
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.UserAdminRepository#load()
+     */
+    public void load()
+    {
+        try
+        {
+            logger.log(LogService.LOG_DEBUG, "Loading User Admin Repository");
+
+            if (repositoryFile == null || !repositoryFile.exists())
+            {
+                repositoryFile = new File(repositoryFileName);
+            }
+
+            if (repositoryFile != null && repositoryFile.exists())
+            {
+                ObjectInputStream ois = new ObjectInputStream(new FileInputStream(repositoryFile));
+                Object obj = ois.readObject();
+                ois.close();
+                if (obj instanceof Hashtable)
+                {
+                    repositoryCache = (Hashtable) obj;
+                    logger.log(LogService.LOG_INFO, "User Admin Repository loaded");
+                }
+                else
+                {
+                    logger.log(LogService.LOG_ERROR, "User Admin Repository corrupted");
+                }
+            }
+            else
+            {
+                logger.log(LogService.LOG_DEBUG, "User Admin Repository not found ");
+            }
+        }
+        catch (IOException e)
+        {
+            logger.log(LogService.LOG_ERROR, "Can't load User Admin Repository", e);
+        }
+        catch (ClassNotFoundException e)
+        {
+            logger.log(LogService.LOG_ERROR, "Can't load User Admin Repository", e);
+        }
+
+        if (repositoryCache == null)
+        {
+            repositoryCache = new Hashtable();
+        }
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.UserAdminRepository#flush()
+     */
+    public void flush()
+    {
+
+        try
+        {
+            if (repositoryFile != null)
+            {
+                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(repositoryFile));
+                oos.writeObject(repositoryCache);
+                oos.close();
+            }
+            else
+            {
+                logger.log(LogService.LOG_DEBUG, "User Admin Repository not found ");
+            }
+        }
+        catch (IOException e)
+        {
+            logger.log(LogService.LOG_ERROR, "Failed to save roles", e);
+        }
+
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.UserAdminRepository#getRepositoryCache()
+     */
+    public Hashtable getRepositoryCache()
+    {
+        return repositoryCache;
+    }
+}

Added: felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryManagerImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryManagerImpl.java?rev=888101&view=auto
==============================================================================
--- felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryManagerImpl.java (added)
+++ felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminRepositoryManagerImpl.java Mon Dec  7 19:32:28 2009
@@ -0,0 +1,259 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.felix.useradmin.impl;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.felix.useradmin.UserAdminRepository;
+import org.apache.felix.useradmin.UserAdminRepositoryManager;
+import org.apache.felix.useradmin.Version;
+import org.osgi.framework.Filter;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.Role;
+
+/**
+ * This class <tt>UserAdminRepositoryManagerImpl</tt> implements UserAdminRepositoryManager.
+ * Providing operations for saving,removing,flushing data to the repository.
+ * All public method are guarded by lock.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class UserAdminRepositoryManagerImpl implements UserAdminRepositoryManager
+{
+    private Logger logger;
+    private Object lock = new Object();
+    private UserAdminRepository store;
+
+    /**
+     * Constructs manager for UserAdminRepositoryManager.
+     * @param logger Logger instance.
+     * @param store backing store instance.
+     */
+    public UserAdminRepositoryManagerImpl(Logger logger, UserAdminRepository store)
+    {
+        this.logger = logger;
+        this.store = store;
+
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.UserAdminRepositoryManager#initialize(org.apache.felix.useradmin.impl.UserAdminServiceImpl)
+     */
+    public void initialize(UserAdminServiceImpl userAdmin)
+    {
+        logger.log(LogService.LOG_DEBUG, "Initializing repository manager");
+        synchronized (lock)
+        {
+            store.load();
+            Hashtable cache = store.getRepositoryCache();
+            initializePredefinedRole(cache);
+            injectDependencyToEntity(cache, userAdmin);
+        }
+
+    }
+
+    /**
+     * Initialising predefined Role Role.USER_ANYONE.
+     * @param storeCache store cache.
+     */
+    private void initializePredefinedRole(Hashtable storeCache)
+    {
+        RoleImpl role = new RoleImpl();
+        role.setName(Role.USER_ANYONE);
+        storeCache.put(Role.USER_ANYONE, role);
+    }
+
+    /**
+     * Injects UserAdmin to Role objects during the startup
+     * @param storeCache cache of the store.
+     * @param userAdmin UserAdmin instance.
+     */
+    private void injectDependencyToEntity(Hashtable storeCache, UserAdminServiceImpl userAdmin)
+    {
+        Enumeration en = storeCache.elements();
+        while (en.hasMoreElements())
+        {
+            RoleImpl role = (RoleImpl) en.nextElement();
+            role.setUserAdmin(userAdmin);
+        }
+    }
+
+    /**
+     * @see org.apache.felix.useradmin.UserAdminRepositoryManager#findRoleByName(java.lang.String)
+     */
+    public Role findRoleByName(String name)
+    {
+        if (name != null)
+        {
+            Hashtable cache = store.getRepositoryCache();
+            return (Role) cache.get(name);
+        }
+        return null;
+    }
+
+    /**
+     * @GuardedBy lock.
+     * @see org.apache.felix.useradmin.UserAdminRepositoryManager#findRoleByTypeAndKeyValue(int,
+     * java.lang.String, java.lang.String)
+     */
+    public Object findRoleByTypeAndKeyValue(int roleType, String key, String value)
+    {
+        synchronized (lock)
+        {
+            Vector temp = new Vector();
+            Hashtable cache = store.getRepositoryCache();
+            for (Enumeration en = cache.elements(); en.hasMoreElements();)
+            {
+                Role role = (Role) en.nextElement();
+                if (role.getType() == roleType)
+                {
+                    Dictionary properties = role.getProperties();
+                    Object val = properties.get(key);
+                    if (value.equals(val))
+                    {
+                        temp.add(role);
+                    }
+                }
+            }
+            return temp.isEmpty() || temp.size() > 1 ? null : temp.get(0);
+        }
+
+    }
+
+    /**
+     * <p>If a null filter is specified, all Role objects managed by User Admin service 
+     * are returned.</p>
+     * 
+     * @GuardedBy lock.
+     * @see org.apache.felix.useradmin.impl.UserAdminRepositoryManager#findRolesByFilter(org.osgi.framework.Filter)
+     */
+    public Role[] findRolesByFilter(Filter filter)
+    {
+        synchronized (lock)
+        {
+            Hashtable cache = store.getRepositoryCache();
+            Enumeration en = cache.elements();
+            if (filter == null)
+            {
+                Role[] rs = new Role[cache.size()];
+                for (int i = 0; en.hasMoreElements(); i++)
+                {
+                    Role role = (Role) en.nextElement();
+                    rs[i] = role;
+                }
+                return rs;
+            }
+            else
+            {
+                Vector temp = new Vector();
+                for (int i = 0; en.hasMoreElements(); i++)
+                {
+                    Role role = (Role) en.nextElement();
+                    if (filter.match(role.getProperties()))
+                    {
+                        temp.add(role);
+                    }
+                }
+                Role[] rs = new Role[temp.size()];
+                temp.copyInto(rs);
+
+                return rs;
+            }
+        }
+    }
+
+    /**
+     * @GuardedBy lock.
+     * @see org.apache.felix.useradmin.impl.UserAdminRepositoryManager#save(java.lang.String, int,
+     * org.apache.felix.useradmin.impl.UserAdminServiceImpl)
+     */
+    public Role save(String name, int type, UserAdminServiceImpl userAdmin)
+    {
+        synchronized (lock)
+        {
+            Role role = (Role) findRoleByName(name);
+            if (role != null)
+            {
+                return null;
+            }
+
+            switch (type)
+            {
+                case Role.USER:
+                    role = new UserImpl();
+                    ((RoleImpl) role).setName(name);
+                    ((RoleImpl) role).setUserAdmin(userAdmin);
+                    break;
+                case Role.GROUP:
+                    role = new GroupImpl();
+                    ((RoleImpl) role).setName(name);
+                    ((RoleImpl) role).setUserAdmin(userAdmin);
+                    break;
+                default:
+                    throw new IllegalArgumentException();
+            }
+
+            Version versionableRole = (Version) role;
+            versionableRole.increaseVersion();
+            Hashtable cache = store.getRepositoryCache();
+            cache.put(role.getName(), role);
+            store.flush();
+            return role;
+        }
+    }
+
+    /**
+     * @GuardedBy lock.
+     * @see org.apache.felix.useradmin.UserAdminRepositoryManager#remove(java.lang.String)
+     */
+    public Role remove(String name)
+    {
+        synchronized (lock)
+        {
+            if (name == null)
+            {
+                return null;
+            }
+            Hashtable cache = store.getRepositoryCache();
+            Role role = (Role) cache.remove(name);
+            if (role != null)
+            {
+                store.flush();
+            }
+            return role;
+        }
+
+    }
+
+    /**
+     * Flushing store cache content into the repository file.
+     * @GuardedBy lock.
+     * @see org.apache.felix.useradmin.UserAdminRepository#flush()
+     */
+    public void flush()
+    {
+        logger.log(LogService.LOG_DEBUG, "Flushing current state of repository cache into the file");
+        synchronized (lock)
+        {
+            store.flush();
+        }
+
+    }
+}

Added: felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminServiceImpl.java?rev=888101&view=auto
==============================================================================
--- felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminServiceImpl.java (added)
+++ felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserAdminServiceImpl.java Mon Dec  7 19:32:28 2009
@@ -0,0 +1,300 @@
+/**
+ *  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.useradmin.impl;
+
+import org.apache.felix.useradmin.CredentialAuthenticator;
+import org.apache.felix.useradmin.UserAdminRepositoryManager;
+import org.apache.felix.useradmin.UserAdminEventDispatcher;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+import org.osgi.service.useradmin.UserAdminEvent;
+import org.osgi.service.useradmin.UserAdminPermission;
+
+/**
+ * <p>
+ * This <tt>UserAdminServiceImpl</tt> class implementing a contract UserAdmin. It represents UserAdmin service is
+ * exposed as a OSGi service in the ServiceRegistry.
+ * </p>
+ * <p>
+ * Its used to manage a database of named Role objects, which can be used for authentication and authorization purposes.
+ * This version of the User Admin service defines two types of Role objects: User and Group. Each type of role is
+ * represented by an int constant and an interface. The range of positive integers is reserved for new types of roles
+ * that may be added in the future. When defining proprietary role types, negative constant values must be used. Every
+ * role has a name and a type. A User object can be configured with credentials (e.g., a password) and properties (e.g.,
+ * a street address, phone number, etc.). A Group object represents an aggregation of User and Group objects. In other
+ * words, the members of a Group object are roles themselves. Every User Admin service manages and maintains its own
+ * namespace of Role objects, in which each Role object has a unique name.
+ * </p>
+ * 
+ * @see org.osgi.service.useradmin.UserAdmin
+ * @see org.osgi.framework.ServiceFactory
+ * @see org.apache.felix.useradmin.UserAdminRepositoryManager
+ * @see org.apache.felix.useradmin.UserAdminEventDispatcher
+ * 
+ * @version $Rev$ $Date$
+ */
+public class UserAdminServiceImpl implements UserAdmin, ServiceFactory
+{
+    private BundleContext bc;
+    /**
+     * This variable represents admin name permission for using UserAdmin.
+     */
+    private UserAdminPermission userAdminPermission;
+    private UserAdminEventDispatcher eventDispatcher;
+    /**
+     * This variable represents state of a service. if is alive is set to true if not false.
+     */
+    private boolean alive;
+    /**
+     * This variable represents ServicReference for this service. Its needed for sending events.
+     */
+    private ServiceReference serviceRef;
+    /**
+     * This variable represents repository manager.
+     */
+    private UserAdminRepositoryManager repositoryManager;
+    private Logger logger;
+    private CredentialAuthenticator authenticator;
+
+    /**
+     * This constructor is creating new UserAdmin service.
+     * 
+     * @param bc BundleContext of a bundle which creating this service instance.
+     * @param repositoryManager repository manager.
+     * @param logger Logger instance.
+     * @param dispatcher UserAdmin event dispatcher instance.
+     */
+    public UserAdminServiceImpl(BundleContext bc, UserAdminRepositoryManager repositoryManager, Logger logger,
+        UserAdminEventDispatcher dispatcher)
+    {
+        this.bc = bc;
+        this.userAdminPermission = new UserAdminPermission(UserAdminPermission.ADMIN, null);
+        this.eventDispatcher = dispatcher;
+        this.eventDispatcher.start();
+        this.repositoryManager = repositoryManager;
+        this.logger = logger;
+        this.alive = true;
+        this.authenticator = new CredentialAuthenticatorImpl();
+
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.UserAdmin#createRole(String, int)
+     */
+    public Role createRole(String name, int type)
+    {
+        checkPermission(userAdminPermission);
+        Role role = repositoryManager.save(name, type, this);
+        if (role != null)
+        {
+            // dispatching an event about created role.
+            eventDispatcher.dispatchEventAsynchronusly(new UserAdminEvent(serviceRef, UserAdminEvent.ROLE_CREATED, role));
+        }
+        return role;
+    }
+
+    /**
+     * Checking permission with security manager. If the caller thread doesn't have permission it throwing
+     * SecurityException.
+     * 
+     * @see java.lang.SecurityManager#checkPermission(java.security.Permission)
+     * @param permission
+     *            UserAdminPermission for which check will e performed.
+     */
+    public void checkPermission(UserAdminPermission permission)
+    {
+        SecurityManager securityManager = System.getSecurityManager();
+        if (securityManager != null)
+        {
+            securityManager.checkPermission(permission);
+        }
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.UserAdmin#getAuthorization(User)
+     */
+    public Authorization getAuthorization(User user)
+    {
+        return new AuthorizationImpl(user, this);
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.UserAdmin#getRole(String)
+     */
+    public Role getRole(String name)
+    {
+        return repositoryManager.findRoleByName(name);
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.UserAdmin#getRoles(String)
+     * @see org.osgi.framework.Filter
+     */
+    public Role[] getRoles(String filter) throws InvalidSyntaxException
+    {
+        // osgi filter
+        Filter ofilter = null;
+        if (filter != null)
+        {
+            // creating a OSGi Filter for provided filter criteria
+            // filter is used for finding matching Roles.
+            ofilter = bc.createFilter(filter);
+        }
+
+        return repositoryManager.findRolesByFilter(ofilter);
+
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.UserAdmin#getUser(String, String)
+     */
+    public User getUser(String key, String value)
+    {
+        return (User) repositoryManager.findRoleByTypeAndKeyValue(Role.USER, key, value);
+
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.UserAdmin#removeRole(String)
+     */
+    public boolean removeRole(String name)
+    {
+        checkPermission(userAdminPermission);
+        if (Role.USER_ANYONE.equals(name))
+        {
+            return false;
+        }
+        Role role = repositoryManager.remove(name);
+        if (role != null)
+        {
+            eventDispatcher.dispatchEventAsynchronusly(new UserAdminEvent(serviceRef, UserAdminEvent.ROLE_REMOVED, role));
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @see org.osgi.framework.ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)
+     */
+    public Object getService(Bundle bundle, ServiceRegistration reg)
+    {
+        return this;
+    }
+
+    /**
+     * @see org.osgi.framework.ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)
+     */
+    public void ungetService(Bundle bundle, ServiceRegistration reg, Object obj)
+    {
+        // not used
+    }
+
+    /**
+     * <p>
+     * This method is closing UserAdmin resources. Should be used when UserAdmin service is unregistred. Alive flag is
+     * set to true, eventDispacther is closed and ServiceReference is set to null.
+     *</p>
+     */
+    public void destroy()
+    {
+        logger.log(LogService.LOG_DEBUG, "Closing UserAdmin service");
+        alive = false;
+        eventDispatcher.close();
+        serviceRef = null;
+        authenticator = null;
+    }
+
+    /**
+     * Checks if UserAdmin service is alive.
+     * 
+     * @return true if service is alive or false if not.
+     */
+    public boolean isAlive()
+    {
+        return alive;
+    }
+
+    /**
+     * This method is used for setting ServiceReference of this service.
+     * 
+     * @param serviceRef ServiceReference of this service.
+     */
+    public void setServiceRef(ServiceReference serviceRef)
+    {
+        this.serviceRef = serviceRef;
+    }
+
+    /**
+     * This method returns ServiceReference for this service needed for UserAdminEvent.
+     * 
+     * @return ServiceReference for this service.
+     */
+    public ServiceReference getServiceRef()
+    {
+        return serviceRef;
+    }
+
+    /**
+     * This method returns UserAdminPermission with name admin.
+     * 
+     * @return UserAdmingPermission with name admin.
+     */
+    public UserAdminPermission getUserAdminPermission()
+    {
+        return userAdminPermission;
+    }
+
+    /**
+     * This method returns UserAdminEvent dispatcher.
+     * 
+     * @return UserAdminEventDispatcher
+     * @see org.apache.felix.useradmin.UserAdminEventDispatcher
+     */
+    public UserAdminEventDispatcher getEventAdminDispatcher()
+    {
+        return eventDispatcher;
+    }
+
+    /**
+     * This method returns repository manager instance.
+     * 
+     * @return repository manager instance.
+     */
+    public UserAdminRepositoryManager getRepositoryManager()
+    {
+        return repositoryManager;
+    }
+
+    /**
+     * This method returns CredentialAuthenticator instance.
+     * @return CredentialAuthenticator instance.
+     */
+    public CredentialAuthenticator getAuthenticator()
+    {
+        return this.authenticator;
+    }
+}

Added: felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserImpl.java?rev=888101&view=auto
==============================================================================
--- felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserImpl.java (added)
+++ felix/trunk/useradmin/src/main/java/org/apache/felix/useradmin/impl/UserImpl.java Mon Dec  7 19:32:28 2009
@@ -0,0 +1,114 @@
+/**
+ *  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.useradmin.impl;
+
+import java.util.Dictionary;
+
+import org.apache.felix.useradmin.CredentialAuthenticator;
+import org.osgi.service.useradmin.Role;
+import org.osgi.service.useradmin.User;
+
+/**
+ * <p>
+ * This <tt>UserImpl</tt>class represents User role.
+ * A User can be configured with credentials, password,properties etc.<p>
+ * 
+ * @see org.osgi.service.useradmin.Role
+ * @see org.osgi.service.useradmin.User
+ * @version $Rev$ $Date$
+ */
+public class UserImpl extends RoleImpl implements User
+{
+    private static final long serialVersionUID = 9207444218182653967L;
+    /**
+     * this variable represents user credentials.
+     */
+    private Dictionary credentials;
+
+    /**
+     * Constructs new User. 
+     */
+    public UserImpl()
+    {
+        super();
+        this.credentials = new RoleCredentials(this);
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.User#getCredentials()
+     */
+    public Dictionary getCredentials()
+    {
+        return credentials;
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.User#hasCredential(String, Object)
+     */
+    public boolean hasCredential(String key, Object value)
+    {
+        if (!userAdmin.isAlive())
+        {
+            throw new IllegalStateException("User Admin Service is not available");
+        }
+        Object rvalue = credentials.get(key);
+        if (rvalue == null)
+        {
+            return false;
+        }
+        CredentialAuthenticator authenticator = userAdmin.getAuthenticator();
+        if (authenticator == null)
+        {
+            return false;
+        }
+
+        if (value instanceof String || value instanceof byte[])
+        {
+            return authenticator.authenticate(value, rvalue);
+        }
+        else
+        {
+            throw new IllegalArgumentException("value must be of type String or byte[]");
+        }
+
+    }
+
+    /**
+     * @see org.osgi.service.useradmin.User#getType()
+     */
+    public int getType()
+    {
+        return Role.USER;
+    }
+
+    /**
+     * Checks if this role is implied by provided Authorization object.
+     * @see org.osgi.service.useradmin.Autorization
+     * @param authorization Authorization instance.
+     * @return true if is implied false if not.
+     */
+    protected boolean impliedBy(AuthorizationImpl authorization)
+    {
+        if (!userAdmin.isAlive())
+        {
+            throw new IllegalStateException("User Admin Service is not available");
+        }
+        String rolename = authorization.getName();
+        boolean implied = (rolename != null && rolename.equals(name)) || name.equals(Role.USER_ANYONE);
+        return implied;
+    }
+}