com.sun.enterprise.security.jacc.provider.SharedState Maven / Gradle / Ivy
Show all versions of payara-micro Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.security.jacc.provider;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
/**
*
* @author monzillo
*/
public class SharedState {
//lock on the shared configTable and linkTable
private static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true);
private static Lock rLock = rwLock.readLock();
private static Lock wLock = rwLock.writeLock();
private static HashMap configTable =
new HashMap();
private static HashMap> linkTable =
new HashMap>();
private static final Logger logger =
Logger.getLogger(SharedState.class.getPackage().getName());
private SharedState() {
}
static Logger getLogger() {
return logger;
}
static SimplePolicyConfiguration lookupConfig(String pcid) {
SimplePolicyConfiguration pc = null;
wLock.lock();
try {
pc = configTable.get(pcid);
} finally {
wLock.unlock();
}
return pc;
}
static SimplePolicyConfiguration getConfig(String pcid, boolean remove) {
SimplePolicyConfiguration pc = null;
wLock.lock();
try {
pc = configTable.get(pcid);
if (pc == null) {
pc = new SimplePolicyConfiguration(pcid);
SharedState.initLinks(pcid);
configTable.put(pcid, pc);
} else if (remove) {
SharedState.removeLinks(pcid);
}
} finally {
wLock.unlock();
}
return pc;
}
static SimplePolicyConfiguration getActiveConfig()
throws PolicyContextException {
String pcid = PolicyContext.getContextID();
SimplePolicyConfiguration pc = null;
if (pcid != null) {
rLock.lock();
try {
pc = configTable.get(pcid);
if (pc == null) {
/* unknown policy context set on thread
* return null to allow checking to be performed with
* default context. Should repair improper setting
* of context by encompassing runtime.
*/
SimplePolicyConfiguration.logException(Level.WARNING,
"invalid policy context id",
new PolicyContextException());
}
} finally {
rLock.unlock();
}
if (pc != null) {
if (!pc.inService()) {
/* policy context set on thread is not in service
* return null to allow checking to be performed with
* default context. Should repair improper setting
* of context by encompassing runtime.
*/
SimplePolicyConfiguration.logException(Level.FINEST,
"invalid policy context state",
new PolicyContextException());
pc = null;
}
}
}
return pc;
}
/**
* Creates a relationship between this configuration and another
* such that they share the same principal-to-role mappings.
* PolicyConfigurations are linked to apply a common principal-to-role
* mapping to multiple seperately manageable PolicyConfigurations,
* as is required when an application is composed of multiple
* modules.
*
* Note that the policy statements which comprise a role, or comprise
* the excluded or unchecked policy collections in a PolicyConfiguration
* are unaffected by the configuration being linked to another.
*
* The relationship formed by this method is symetric, transitive
* and idempotent.
* @param id
* @param otherId
* @throws javax.security.jacc.PolicyContextException If otherID
* equals receiverID. no relationship is formed.
*/
static void link(String id, String otherId)
throws javax.security.jacc.PolicyContextException {
wLock.lock();
try {
if (otherId.equals(id)) {
String msg = "Operation attempted to link PolicyConfiguration to itself.";
throw new IllegalArgumentException(msg);
}
// get the linkSet corresponding to this context
HashSet linkSet = linkTable.get(id);
// get the linkSet corresponding to the context being linked to this
HashSet otherLinkSet = linkTable.get(otherId);
if (otherLinkSet == null) {
String msg = "Linked policy configuration (" + otherId + ") does not exist";
throw new RuntimeException(msg);
}
Iterator it = otherLinkSet.iterator();
// for each context (id) linked to the context being linked to this
while (it.hasNext()) {
String nextid = (String) it.next();
//add the id to this linkSet
linkSet.add(nextid);
//replace the linkset mapped to all the contexts being linked
//to this context, with this linkset.
linkTable.put(nextid, linkSet);
}
} finally {
wLock.unlock();
}
}
static void initLinks(String id) {
// create a new linkSet with only this context id, and put in the table.
HashSet linkSet = new HashSet();
linkSet.add(id);
linkTable.put(id, linkSet);
}
static void removeLinks(String id) {
wLock.lock();
try { // get the linkSet corresponding to this context.
HashSet linkSet = linkTable.get(id);
// remove this context id from the linkSet (which may be shared
// with other contexts), and unmap the linkSet from this context.
if (linkSet != null) {
linkSet.remove(id);
linkTable.remove(id);
}
initLinks(id);
} finally {
wLock.unlock();
}
}
}