001package org.apache.fulcrum.security.spi;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021import org.apache.commons.lang3.StringUtils;
022import org.apache.fulcrum.security.PermissionManager;
023import org.apache.fulcrum.security.entity.Permission;
024import org.apache.fulcrum.security.util.DataBackendException;
025import org.apache.fulcrum.security.util.EntityExistsException;
026import org.apache.fulcrum.security.util.UnknownEntityException;
027
028/**
029 * This implementation keeps all objects in memory. This is mostly meant to help
030 * with testing and prototyping of ideas.
031 *
032 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
033 * @version $Id: AbstractPermissionManager.java 1372918 2012-08-14 15:19:40Z tv
034 *          $
035 */
036public abstract class AbstractPermissionManager extends AbstractEntityManager implements PermissionManager
037{
038    /**
039     * 
040     */
041    private static final long serialVersionUID = 1L;
042
043    protected abstract <T extends Permission> T persistNewPermission(T permission) throws DataBackendException;
044
045    /**
046     * Construct a blank Permission object.
047     *
048     * This method calls getPermissionClass, and then creates a new object using
049     * the default constructor.
050     *
051     * @return an object implementing Permission interface.
052     * @throws DataBackendException
053     *             if the object could not be instantiated.
054     */
055    @Override
056        public <T extends Permission> T getPermissionInstance() throws DataBackendException
057    {
058        try
059        {
060            @SuppressWarnings("unchecked")
061                        T permission = (T) Class.forName(getClassName()).newInstance();
062            return permission;
063        }
064        catch (Exception e)
065        {
066            throw new DataBackendException("Failed to instantiate a Permission implementation object", e);
067        }
068    }
069
070    /**
071     * Construct a blank Permission object.
072     *
073     * This method calls getPermissionClass, and then creates a new object using
074     * the default constructor.
075     *
076     * @param permName
077     *            The name of the permission.
078     *
079     * @return an object implementing Permission interface.
080     * @throws DataBackendException
081     *             if the object could not be instantiated.
082     */
083    @Override
084        public <T extends Permission> T getPermissionInstance(String permName) throws DataBackendException
085    {
086        T perm = getPermissionInstance();
087        perm.setName(permName);
088        return perm;
089    }
090
091    /**
092     * Retrieve a Permission object with specified name.
093     *
094     * @param name
095     *            the name of the Permission.
096     * @return an object representing the Permission with specified name.
097     * @throws DataBackendException
098     *             if there was an error accessing the data backend.
099     * @throws UnknownEntityException
100     *             if the permission does not exist.
101     */
102    @Override
103        public <T extends Permission> T getPermissionByName(String name) throws DataBackendException, UnknownEntityException
104    {
105        @SuppressWarnings("unchecked")
106                T permission = (T) getAllPermissions().getByName(name);
107        if (permission == null)
108        {
109            throw new UnknownEntityException("The specified permission does not exist");
110        }
111        return permission;
112    }
113
114    /**
115     * Retrieve a Permission object with specified Id.
116     *
117     * @param id
118     *            the ID of the Permission.
119     *
120     * @return an object representing the Permission with specified name.
121     *
122     * @throws UnknownEntityException
123     *             if the permission does not exist in the database.
124     * @throws DataBackendException
125     *             if there is a problem accessing the storage.
126     */
127    @Override
128        public <T extends Permission> T getPermissionById(Object id) throws DataBackendException, UnknownEntityException
129    {
130        @SuppressWarnings("unchecked")
131                T permission = (T) getAllPermissions().getById(id);
132        if (permission == null)
133        {
134            throw new UnknownEntityException("The specified permission does not exist");
135        }
136        return permission;
137    }
138
139    /**
140     * Creates a new permission with specified attributes.
141     *
142     * @param permission
143     *            the object describing the permission to be created.
144     * @return a new Permission object that has id set up properly.
145     * @throws DataBackendException
146     *             if there was an error accessing the data backend.
147     * @throws EntityExistsException
148     *             if the permission already exists.
149     */
150    @Override
151        public synchronized <T extends Permission> T addPermission(T permission) throws DataBackendException, EntityExistsException
152    {
153        boolean permissionExists = false;
154        if (StringUtils.isEmpty(permission.getName()))
155        {
156            throw new DataBackendException("Could not create a permission with empty name!");
157        }
158//        if (permission.getId() == null)
159//        {
160//            throw new DataBackendException("Could not create a permission with an id of null!");
161//        }
162        try
163        {
164            permissionExists = checkExists(permission);
165            if (!permissionExists)
166            {
167                return persistNewPermission(permission);
168            }
169        }
170        catch (Exception e)
171        {
172            throw new DataBackendException("addPermission(Permission) failed", e);
173        }
174        // the only way we could get here without return/throw triggered
175        // is that the permissionExists was true.
176        throw new EntityExistsException("Permission '" + permission + "' already exists");
177    }
178
179    /**
180     * Check whether a specified permission exists.
181     *
182     * The name is used for looking up the permission
183     *
184     * @param permission
185     *            The permission to be checked.
186     * @return true if the specified permission exists
187     * @throws DataBackendException
188     *             if there was an error accessing the data backend.
189     */
190    @Override
191        public boolean checkExists(Permission permission) throws DataBackendException
192    {
193        return checkExists(permission.getName());
194    }
195
196}