Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyScanner.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyScanner.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyScanner.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyScanner.java Mon Jan 9 13:12:52 2012 @@ -167,19 +167,19 @@ public class DefaultPolicyScanner { */ protected KeystoreEntry readKeystoreEntry(StreamTokenizer st) throws IOException, InvalidFormatException { - KeystoreEntry ke = new KeystoreEntry(); + String url = null, type = null; if (st.nextToken() == '"') { - ke.url = st.sval; + url = st.sval; if ((st.nextToken() == '"') || ((st.ttype == ',') && (st.nextToken() == '"'))) { - ke.type = st.sval; + type = st.sval; } else { // handle token in the main loop st.pushBack(); } } else { handleUnexpectedToken(st, Messages.getString("security.8A")); //$NON-NLS-1$ } - return ke; + return new KeystoreEntry(url, type); } /** @@ -207,25 +207,28 @@ public class DefaultPolicyScanner { */ protected GrantEntry readGrantEntry(StreamTokenizer st) throws IOException, InvalidFormatException { - GrantEntry ge = new GrantEntry(); + String signer = null, codebase = null; + Collection<PrincipalEntry> principals = new ArrayList<PrincipalEntry>(); + Collection<PermissionEntry> permissions = null; + parsing: while (true) { switch (st.nextToken()) { case StreamTokenizer.TT_WORD: if (Util.equalsIgnoreCase("signedby", st.sval)) { //$NON-NLS-1$ if (st.nextToken() == '"') { - ge.setSigners(st.sval); + signer = st.sval; } else { handleUnexpectedToken(st, Messages.getString("security.8B")); //$NON-NLS-1$ } } else if (Util.equalsIgnoreCase("codebase", st.sval)) { //$NON-NLS-1$ if (st.nextToken() == '"') { - ge.setCodebase(st.sval); + codebase = st.sval; } else { handleUnexpectedToken(st, Messages.getString("security.8C")); //$NON-NLS-1$ } } else if (Util.equalsIgnoreCase("principal", st.sval)) { //$NON-NLS-1$ - ge.addPrincipal(readPrincipalEntry(st)); + principals.add(readPrincipalEntry(st)); } else { handleUnexpectedToken(st); } @@ -235,7 +238,7 @@ public class DefaultPolicyScanner { break; case '{': - ge.setPermissions(readPermissionEntries(st)); + permissions = readPermissionEntries(st); break parsing; default: // handle token in the main loop @@ -244,7 +247,7 @@ public class DefaultPolicyScanner { } } - return ge; + return new GrantEntry(signer, codebase, principals, permissions); } /** @@ -267,22 +270,22 @@ public class DefaultPolicyScanner { */ protected PrincipalEntry readPrincipalEntry(StreamTokenizer st) throws IOException, InvalidFormatException { - PrincipalEntry pe = new PrincipalEntry(); + String classname = null, name = null; if (st.nextToken() == StreamTokenizer.TT_WORD) { - pe.klass = st.sval; + classname = st.sval; st.nextToken(); } else if (st.ttype == '*') { - pe.klass = PrincipalEntry.WILDCARD; + classname = PrincipalEntry.WILDCARD; st.nextToken(); } if (st.ttype == '"') { - pe.name = st.sval; + name = st.sval; } else if (st.ttype == '*') { - pe.name = PrincipalEntry.WILDCARD; + name = PrincipalEntry.WILDCARD; } else { handleUnexpectedToken(st, Messages.getString("security.8D")); //$NON-NLS-1$ } - return pe; + return new PrincipalEntry(classname, name); } /** @@ -313,18 +316,19 @@ public class DefaultPolicyScanner { case StreamTokenizer.TT_WORD: if (Util.equalsIgnoreCase("permission", st.sval)) { //$NON-NLS-1$ - PermissionEntry pe = new PermissionEntry(); + String klass = null, name = null, actions = null, signers = null; + if (st.nextToken() == StreamTokenizer.TT_WORD) { - pe.klass = st.sval; + klass = st.sval; if (st.nextToken() == '"') { - pe.name = st.sval; + name = st.sval; st.nextToken(); } if (st.ttype == ',') { st.nextToken(); } if (st.ttype == '"') { - pe.actions = st.sval; + actions = st.sval; if (st.nextToken() == ',') { st.nextToken(); } @@ -332,13 +336,14 @@ public class DefaultPolicyScanner { if (st.ttype == StreamTokenizer.TT_WORD && Util.equalsIgnoreCase("signedby", st.sval)) { //$NON-NLS-1$ if (st.nextToken() == '"') { - pe.signers = st.sval; + signers = st.sval; } else { handleUnexpectedToken(st); } } else { // handle token in the next iteration st.pushBack(); } + PermissionEntry pe = new PermissionEntry(klass, name, actions, signers); permissions.add(pe); continue parsing; } @@ -417,23 +422,42 @@ public class DefaultPolicyScanner { /** * The URL part of keystore clause. */ - public String url; + private final String url; /** * The typename part of keystore clause. */ - public String type; + private final String type; + + KeystoreEntry(String url, String type){ + this.url= url; + this.type= type; + } public String toString(){ String newline = "\n"; - int l = url == null? 0 : url.length(); - l = l + type == null? 0 : type.length(); + int l = getUrl() == null? 0 : getUrl().length(); + l = l + (getType() == null? 0 : getType().length()); l = l + 4; StringBuffer sb = new StringBuffer(l); - if ( url != null ) sb.append(url).append(newline); - if ( type != null ) sb.append(type).append(newline); + if ( getUrl() != null ) sb.append(getUrl()).append(newline); + if ( getType() != null ) sb.append(getType()).append(newline); return sb.toString(); } + + /** + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * @return the type + */ + public String getType() { + return type; + } } /** @@ -449,63 +473,48 @@ public class DefaultPolicyScanner { * The signers part of grant clause. This is a comma-separated list of * certificate aliases. */ - private String signers; + private final String signers; /** * The codebase part of grant clause. This is an URL from which code * originates. Comma separate list allowed? */ - private String codebase; - - /** - * If there is an array string of codebases, use this field instead. - */ - private Collection<String> codebases; + private final String codebase; /** * Collection of PrincipalEntries of grant clause. */ - private Collection<PrincipalEntry> principals; + private final Collection<PrincipalEntry> principals; /** * Collection of PermissionEntries of grant clause. */ - private Collection<PermissionEntry> permissions; + private final Collection<PermissionEntry> permissions; + + GrantEntry(String signers, String codebase, + Collection<PrincipalEntry> pe, + Collection<PermissionEntry> perms){ + this.signers = signers; + this.codebase = codebase; + this.principals = pe; + this.permissions = perms; + } public String toString(){ String newline = "\n"; - StringBuffer sb = new StringBuffer(400); + StringBuilder sb = new StringBuilder(400); if (signers != null ) sb.append(signers).append(newline); if (codebase != null ) sb.append(codebase).append(newline); - if (codebases != null ) sb.append(codebases).append(newline); if (principals != null ) sb.append(principals).append(newline); if (permissions != null ) sb.append(permissions).append(newline); return sb.toString(); } /** - * Adds specified element to the <code>principals</code> collection. - * If collection does not exist yet, creates a new one. - */ - public void addPrincipal(PrincipalEntry pe) { - if (getPrincipals(null) == null) { - setPrincipals(new HashSet<PrincipalEntry>()); - } - getPrincipals(null).add(pe); - } - - /** * @return the signers */ public String getSigners() { return signers; - } - - /** - * @param signers the signers to set - */ - public void setSigners(String signers) { - this.signers = signers; } /** @@ -523,14 +532,6 @@ public class DefaultPolicyScanner { } /** - * Set the the codebase string. - * @param codebase the codebase to set - */ - public void setCodebase(String codebase) { - this.codebase = codebase; - } - - /** * @return the principals */ public Collection<PrincipalEntry> getPrincipals(Properties system) { @@ -538,26 +539,12 @@ public class DefaultPolicyScanner { } /** - * @param principals the principals to set - */ - public void setPrincipals(Collection<PrincipalEntry> principals) { - this.principals = principals; - } - - /** * @return the permissions */ public Collection<PermissionEntry> getPermissions() { return permissions; } - /** - * @param permissions the permissions to set - */ - public void setPermissions(Collection<PermissionEntry> permissions) { - this.permissions = permissions; - } - } /** @@ -580,23 +567,42 @@ public class DefaultPolicyScanner { /** * The classname part of principal clause. */ - public String klass; + private final String klass; /** * The name part of principal clause. */ - public String name; + private final String name; + + PrincipalEntry(String classname, String name){ + klass = classname; + this.name = name; + } public String toString(){ String newline = "\n"; - int l = klass == null? 0 : klass.length(); - l = l + name == null? 0 : name.length(); + int l = getKlass() == null? 0 : getKlass().length(); + l = l + getName() == null? 0 : getName().length(); l = l + 4; StringBuffer sb = new StringBuffer(l); - if ( klass != null ) sb.append(klass).append(newline); - if ( name != null ) sb.append(name).append(newline); + if ( getKlass() != null ) sb.append(getKlass()).append(newline); + if ( getName() != null ) sb.append(getName()).append(newline); return sb.toString(); } + + /** + * @return the klass + */ + public String getKlass() { + return klass; + } + + /** + * @return the name + */ + public String getName() { + return name; + } } /** @@ -612,37 +618,73 @@ public class DefaultPolicyScanner { /** * The classname part of permission clause. */ - public String klass; + private final String klass; /** * The name part of permission clause. */ - public String name; + private final String name; /** * The actions part of permission clause. */ - public String actions; + private final String actions; /** * The signers part of permission clause. This is a comma-separated list * of certificate aliases. */ - public String signers; + private final String signers; + + PermissionEntry(String klass, String name, String actions, String signers){ + if (klass == null) throw new NullPointerException(); + this.klass= klass; + this.name= name == null ? "" : name; + this.actions= actions == null ? "" : actions; + this.signers= signers; + } public String toString(){ String endline = "\n"; - int l = klass == null ? 0 : klass.length(); - l = l + name == null? 0 : name.length(); - l = l + actions == null? 0 : actions.length(); - l = l + signers == null? 0 : signers.length(); + int l = getKlass() == null ? 0 : getKlass().length(); + l = l + (getName() == null? 0 : getName().length()); + l = l + (getActions() == null? 0 : getActions().length()); + l = l + (getSigners() == null? 0 : getSigners().length()); l = l + 8; StringBuffer sb = new StringBuffer(l); - if ( klass != null ) sb.append(klass).append(endline); - if ( name != null ) sb.append(name).append(endline); - if ( actions != null ) sb.append(actions).append(endline); - if ( signers != null ) sb.append(signers).append(endline); + if ( getKlass() != null ) sb.append(getKlass()).append(endline); + if ( getName() != null ) sb.append(getName()).append(endline); + if ( getActions() != null ) sb.append(getActions()).append(endline); + if ( getSigners() != null ) sb.append(getSigners()).append(endline); return sb.toString(); } + + /** + * @return the klass + */ + public String getKlass() { + return klass; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @return the actions + */ + public String getActions() { + return actions; + } + + /** + * @return the signers + */ + public String getSigners() { + return signers; + } } }
Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Messages.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Messages.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Messages.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/Messages.java Mon Jan 9 13:12:52 2012 @@ -49,7 +49,19 @@ import java.util.ResourceBundle; public class Messages { // ResourceBundle holding the system messages. - static private ResourceBundle bundle = null; + static final private ResourceBundle bundle ; + + static { + // Attempt to load the messages. + ResourceBundle rb = null; + try { + rb = setLocale(Locale.getDefault(), + "org.apache.river.impl.security.policy.util.messages"); //$NON-NLS-1$ + } catch (Throwable e) { + System.err.println(e); + } + bundle = rb; + } /** * Retrieves a message which has no arguments. @@ -139,6 +151,7 @@ public class Messages { try { format = bundle.getString(msg); } catch (MissingResourceException e) { + System.err.println(e); } } @@ -234,17 +247,10 @@ public class Messages { } }); } catch (MissingResourceException e) { + System.err.println(e); } return null; } - static { - // Attempt to load the messages. - try { - bundle = setLocale(Locale.getDefault(), - "org.apache.river.impl.security.policy.util.messages"); //$NON-NLS-1$ - } catch (Throwable e) { - e.printStackTrace(); - } - } + } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PolicyUtils.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PolicyUtils.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PolicyUtils.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/PolicyUtils.java Mon Jan 9 13:12:52 2012 @@ -44,6 +44,8 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import net.jini.security.ConcurrentPermissions; /** @@ -64,7 +66,7 @@ public class PolicyUtils { /** * URL of target location. */ - public URL location; + private final URL location; /** * Constructor with target URL parameter. @@ -134,7 +136,7 @@ public class PolicyUtils { super(message, cause); } } - + /** * Substitutes all entries like ${some.key}, found in specified string, * for specified values. @@ -146,28 +148,18 @@ public class PolicyUtils { */ public static String expand(String str, Properties properties) throws ExpansionFailedException { - final String ARRAY_START_MARK = "${{"; - final String ARRAY_END_MARK = "}}"; final String START_MARK = "${"; //$NON-NLS-1$ final String END_MARK = "}"; //$NON-NLS-1$ - - if ( str.indexOf(ARRAY_START_MARK) > 0) { - return process(str, properties, ARRAY_START_MARK, ARRAY_END_MARK); - } - return process(str, properties, START_MARK, END_MARK); - } - - private static String process(String str, Properties p, String START_MARK, - String END_MARK) throws ExpansionFailedException{ - StringBuilder result = new StringBuilder(str); final int START_OFFSET = START_MARK.length(); final int END_OFFSET = END_MARK.length(); + + StringBuilder result = new StringBuilder(str); int start = result.indexOf(START_MARK); while (start >= 0) { int end = result.indexOf(END_MARK, start); if (end >= 0) { String key = result.substring(start + START_OFFSET, end); - String value = p.getProperty(key); + String value = properties.getProperty(key); if (value != null) { result.replace(start, end + END_OFFSET, value); start += value.length(); @@ -179,6 +171,15 @@ public class PolicyUtils { } return result.toString(); } + +// public static String expand(String str, Properties properties) throws ExpansionFailedException{ +// Segment s = new Segment(str, null); +// for (int i = 0; i < 3; i++){ //nested properies 3 deep. +// s.divideAndReplace("${", "}", null, properties); +// } +// s.hasNext(); // There will be at least one result +// return s.next(); // Don't bother checking for more, not split into array. +// } /** * Handy shortcut for @@ -199,7 +200,8 @@ public class PolicyUtils { * @throws URISyntaxException */ public static URI normalizeURL(URL codebase) throws URISyntaxException { - if (codebase != null && "file".equals(codebase.getProtocol())) { //$NON-NLS-1$ + if (codebase == null) return null; + if ("file".equals(codebase.getProtocol())) { //$NON-NLS-1$ try { if (codebase.getHost().length() == 0) { String path = codebase.getFile(); @@ -437,7 +439,7 @@ public class PolicyUtils { */ public static PermissionCollection toPermissionCollection(Collection<Permission> perms) { - PermissionCollection pc = new ConcurrentPermissions(); + PermissionCollection pc = new Permissions(); if (perms != null) { for (Iterator<Permission> iter = perms.iterator(); iter.hasNext();) { Permission element = iter.next(); Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java Mon Jan 9 13:12:52 2012 @@ -166,7 +166,7 @@ public class RC { * @return */ public static <T> Collection<T> collection(Collection<Referrer<T>> internal, Ref type){ - return new ReferenceCollection<T>(internal, type); + return new ReferenceCollection<T>(internal, type, false); } // /** @@ -272,7 +272,7 @@ public class RC { return new ReferenceBlockingQueue<T>(internal, type); } /** - * Wrap a Blocki ngDeque for holding references so it appears as a BlockingDeque + * Wrap a BlockingDeque for holding references so it appears as a BlockingDeque * containing referents. * * @param <T> Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java Mon Jan 9 13:12:52 2012 @@ -43,7 +43,7 @@ import java.util.logging.Logger; * * Synchronisation must be implemented by the underlying Collection and cannot * be performed externally to this class. The underlying Collection must - * also be mutable. Object will be removed automatically from the underlying + * also be mutable. Objects will be removed automatically from the underlying * Collection when they are eligible for garbage collection. * * Weak, Weak Identity, Soft, Soft Identity or Strong references may be used. @@ -64,12 +64,12 @@ class ReferenceCollection<T> extends Abs private final ReferenceQueuingFactory<T, Referrer<T>> rqf; private final Ref type; - ReferenceCollection(Collection<Referrer<T>> col, Ref type){ - this(col, new ReferenceProcessor<T>(col, type, type == Ref.STRONG ? null : new ReferenceQueue<T>()), type); + ReferenceCollection(Collection<Referrer<T>> col, Ref type, boolean gcThread){ + this(col, new ReferenceProcessor<T>(col, type, type == Ref.STRONG ? null : new ReferenceQueue<T>(), false), type, false); } ReferenceCollection(Collection<Referrer<T>> col, - ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){ + ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type, boolean gcThread){ this.col = col; this.rqf = rqf; this.type = type; Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceIterator.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceIterator.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceIterator.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceIterator.java Mon Jan 9 13:12:52 2012 @@ -20,6 +20,7 @@ package org.apache.river.impl.util; import java.lang.ref.Reference; import java.util.Iterator; +import java.util.NoSuchElementException; /** * @@ -27,20 +28,30 @@ import java.util.Iterator; */ class ReferenceIterator<T> implements Iterator<T> { private final Iterator<Referrer<T>> iterator; + private T next; ReferenceIterator(Iterator<Referrer<T>> iterator) { if ( iterator == null ) throw new IllegalArgumentException("iterator cannot be null"); this.iterator = iterator; + next = null; } public boolean hasNext() { - return iterator.hasNext(); + while ( iterator.hasNext()){ + Referrer<T> t = iterator.next(); + if ( t != null ) { + next = t.get(); + if (next != null) return true; + else iterator.remove(); // garbage collected. + } + } + next = null; + return false; } public T next() { - Referrer<T> t = iterator.next(); - if ( t != null ) return t.get(); - return null; + if (next == null) throw new NoSuchElementException(); + return next; } public void remove() { Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java Mon Jan 9 13:12:52 2012 @@ -49,12 +49,12 @@ class ReferenceList<T> extends Reference private static final long serialVersionUID = 1L; private final List<Referrer<T>> list; ReferenceList(List<Referrer<T>> list, Ref type){ - super(list, type); + super(list, type, false); this.list = list; } ReferenceList(List<Referrer<T>> list, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){ - super(list, rqf, type); + super(list, rqf, type, false); this.list = list; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java Mon Jan 9 13:12:52 2012 @@ -68,8 +68,8 @@ class ReferenceMap<K, V> extends Abstrac ReferenceMap(Map<Referrer<K>,Referrer<V>> map, Ref key, Ref val){ this(map, - new ReferenceProcessor<K>(map.keySet(), key, new ReferenceQueue<K>()), - new ReferenceProcessor<V>(map.values(), val, new ReferenceQueue<V>()), + new ReferenceProcessor<K>(map.keySet(), key, new ReferenceQueue<K>(), false), + new ReferenceProcessor<V>(map.values(), val, new ReferenceQueue<V>(), false), key, val ); } @@ -80,7 +80,7 @@ class ReferenceMap<K, V> extends Abstrac this.vrqf = vrqf; this.key = key; this.val = val; - values = new ReferenceCollection<V>(this.map.values(), vrqf, val); + values = new ReferenceCollection<V>(this.map.values(), vrqf, val, false); keys = new ReferenceSet<K>(this.map.keySet(), krqf, key); // We let this escape during construction, but it's package private only // and doesn't escape the package. Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceProcessor.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceProcessor.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceProcessor.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceProcessor.java Mon Jan 9 13:12:52 2012 @@ -18,32 +18,87 @@ package org.apache.river.impl.util; +import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; /** - * + * ReferenceProcessor is responsible for creation and collection of References + * on behalf of Reference Collection implementations. * * @param <T> * @author peter */ class ReferenceProcessor<T> implements ReferenceQueuingFactory<T, Referrer<T>> { + private final static ScheduledExecutorService garbageCleaner = + Executors.newScheduledThreadPool(1, new SystemThreadFactory()); + // Map to register newly created object references. + private final static Map<Reference,ScheduledFuture> finalizerTasks = + new ConcurrentHashMap<Reference,ScheduledFuture>(); + // Finalizer queue to advise cancellation of ScheduledFuture's, + // when their ReferenceProcessor has been collected. + private final static ReferenceQueue<Reference> phantomQueue = + new ReferenceQueue<Reference>(); + static { + // Finizer Task to cancel unneeded tasks. + garbageCleaner.scheduleAtFixedRate( + new FinalizerTask(phantomQueue, finalizerTasks), + 5L, 5L, TimeUnit.MINUTES + ); + } + private final Collection<Referrer<T>> col; private final ReferenceQueue<T> queue; private final Ref type; private final Lock queueLock; + private final boolean gcThreads; + private volatile boolean started = false; - ReferenceProcessor(Collection<Referrer<T>> col, Ref type, ReferenceQueue<T> queue){ + ReferenceProcessor(Collection<Referrer<T>> col, Ref type, ReferenceQueue<T> queue, boolean gcThreads){ if (col == null || type == null ) throw new NullPointerException("collection or reference type cannot be null"); this.col = col; this.type = type; this.queue = type == Ref.STRONG ? null : queue; + this.gcThreads = gcThreads; queueLock = new ReentrantLock(); } + + /** + * Register with executor service and finaliser for cleanup. + */ + public void start(){ + if (started) return; // Start once only. + synchronized (this){ + if (started) return; + started = true; + } + ScheduledFuture task; + task = (gcThreads && queue != null) + ? garbageCleaner.scheduleAtFixedRate(new CleanerTask(col, queue), 10L, 10L, TimeUnit.SECONDS) + : null; + if ( task != null ){ + // Register with finaliser. + @SuppressWarnings("unchecked") + Reference r = new PhantomReference(this, phantomQueue); + finalizerTasks.put(r, task); + } + } @Override public T pseudoReferent(Referrer<T> u) { @@ -59,7 +114,7 @@ class ReferenceProcessor<T> implements R @Override public void processQueue() { - if (queue == null) return; + if (queue == null || gcThreads) return; Object t = null; /* * The reason for using an explicit lock is if another thread is @@ -79,4 +134,97 @@ class ReferenceProcessor<T> implements R } } } + + private static class CleanerTask implements Runnable { + + private final Collection col; + private final ReferenceQueue queue; + + private CleanerTask(Collection c, ReferenceQueue queue){ + col = c; + this.queue = queue; + } + + @Override + public void run() { + Object t; + while ( (t = queue.poll()) != null ){ + col.remove(t); + } + } + + } + + private static class FinalizerTask implements Runnable { + + private final ReferenceQueue phantomQueue; + private final Map<Reference,ScheduledFuture> finalizerTasks ; + + private FinalizerTask(ReferenceQueue queue, + Map<Reference,ScheduledFuture> tasks){ + phantomQueue = queue; + finalizerTasks = tasks; + } + + @Override + public void run() { + Reference p; + while ( (p = phantomQueue.poll()) != null){ + ScheduledFuture sf = finalizerTasks.remove(p); + if (sf !=null) sf.cancel(true); + // phantom reference is eligible for gc we don't have to + // clear it, but might as well. + p.clear(); + } + } + + } + + private static class SystemThreadFactory implements ThreadFactory{ + private static final ThreadGroup g; + + static { + ThreadGroup tg = Thread.currentThread().getThreadGroup(); + try { + tg = AccessController.doPrivileged( new ThreadGroupAction(tg)); + } catch (PrivilegedActionException ex) { + Exception e = ex.getException(); + if (e instanceof SecurityException){ + Logger.getLogger(ReferenceProcessor.class.getName()).log(Level.FINE, null, e); + } else if (e instanceof RuntimeException){ + throw (RuntimeException) e; + } + } + g = tg; + } + + private SystemThreadFactory(){ + } + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(g, r); + t.setContextClassLoader(null); + t.setPriority(Thread.MAX_PRIORITY); + return t; + } + + } + + private static class ThreadGroupAction implements PrivilegedExceptionAction<ThreadGroup>{ + private ThreadGroup tg; + + ThreadGroupAction(ThreadGroup g){ + tg = g; + } + public ThreadGroup run() { + ThreadGroup parent = tg.getParent(); + while (parent != null){ + tg = parent; + parent = tg.getParent(); + } + return tg; + } + } + } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java Mon Jan 9 13:12:52 2012 @@ -34,11 +34,11 @@ class ReferenceSet<T> extends ReferenceC private static final long serialVersionUID = 1L; ReferenceSet(Set<Referrer<T>> col, Ref type){ - super(col, type); + super(col, type, false); } ReferenceSet(Set<Referrer<T>> col, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){ - super(col, rqf, type); + super(col, rqf, type, false); } private void readObject(ObjectInputStream stream) Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java Mon Jan 9 13:12:52 2012 @@ -32,7 +32,7 @@ public class ReferencedQueue<T> extends private final Queue<Referrer<T>> queue; public ReferencedQueue( Queue<Referrer<T>> queue, Ref type){ - super(queue, type); + super(queue, type, false); this.queue = queue; } Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/net/jini/security/DynamicPermissionCollectionTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/net/jini/security/DynamicPermissionCollectionTest.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/test/src/net/jini/security/DynamicPermissionCollectionTest.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/test/src/net/jini/security/DynamicPermissionCollectionTest.java Mon Jan 9 13:12:52 2012 @@ -19,6 +19,7 @@ package net.jini.security; +import java.util.TreeSet; import java.util.Collection; import java.io.IOException; import java.io.ByteArrayInputStream; @@ -140,7 +141,7 @@ public class DynamicPermissionCollection expResult.add(permission0); expResult.add(permission1); expResult.add(permission2); - Collection<Permission> result = new ArrayList<Permission>(3); + Collection<Permission> result = new TreeSet<Permission>(new PermissionComparator()); ObjectOutputStream out = null; ObjectInputStream in = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/DefaultPolicyParserTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/DefaultPolicyParserTest.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/DefaultPolicyParserTest.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/DefaultPolicyParserTest.java Mon Jan 9 13:12:52 2012 @@ -22,23 +22,35 @@ package org.apache.river.impl.security.policy.util; +import com.sun.jini.start.SharedActivationPolicyPermission; +import java.net.URISyntaxException; +import java.security.KeyStore; import java.util.Properties; import java.util.SortedSet; import java.io.File; import java.io.FileWriter; +import java.net.URI; import java.net.URL; import java.security.CodeSource; import java.security.Permission; import java.security.Principal; import java.security.SecurityPermission; +import java.security.UnresolvedPermission; import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import junit.framework.TestCase; import org.apache.river.api.security.PermissionGrant; +import org.apache.river.api.security.PermissionGrantBuilder; +import org.apache.river.impl.security.policy.util.DefaultPolicyScanner.GrantEntry; +import org.apache.river.impl.security.policy.util.DefaultPolicyScanner.KeystoreEntry; +import org.apache.river.impl.security.policy.util.DefaultPolicyScanner.PermissionEntry; +import org.junit.Before; import org.junit.Test; @@ -48,10 +60,70 @@ import org.junit.Test; */ public class DefaultPolicyParserTest extends TestCase { - + private Properties system; + private GrantEntry ge; + private Collection<Permission> permissions; + private PermissionGrant grant; + private PermissionEntry pe0, pe1, pe2, pe3; + private Permission perm0, perm1, perm2, perm3; public static void main(String[] args) { junit.textui.TestRunner.run(DefaultPolicyParserTest.class); } + + @Before + public void setUp(){ + system = new Properties(); + system.setProperty("com.sun.jini.jsk.home", "/opt/src/river/trunk"); + system.setProperty("/", "/"); + system.setProperty("com.sun.jini.qa.harness.harnessJar", "/opt/src/river/trunk/qa/lib/harness.jar"); + pe0 = new PermissionEntry("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:${com.sun.jini.qa.harness.harnessJar}!/harness/policy/sec-jeri-group.policy", + null, null ); + pe1 = new PermissionEntry("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:${com.sun.jini.qa.harness.harnessJar}!/harness/policy/all.policy", + null, null ); + pe2 = new PermissionEntry("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:${com.sun.jini.qa.harness.harnessJar}!/harness/policy/policy.all", + null, null ); + pe3 = new PermissionEntry("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:${com.sun.jini.qa.harness.harnessJar}!/harness/policy/defaultgroup.policy", + null, null ); + List<PermissionEntry> pec = new ArrayList<PermissionEntry>(4); + pec.add(0, pe0); + pec.add(1, pe1); + pec.add(2, pe2); + pec.add(3, pe3); + ge = new GrantEntry( null, "file:${com.sun.jini.jsk.home}${/}lib${/}group.jar", null, pec ); + perm0 = new UnresolvedPermission("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:/opt/src/river/trunk/qa/lib/harness.jar!/harness/policy/sec-jeri-group.policy", + "", null); + perm1 = new UnresolvedPermission("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:/opt/src/river/trunk/qa/lib/harness.jar!/harness/policy/all.policy", + "", null); + perm2 = new UnresolvedPermission("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:/opt/src/river/trunk/qa/lib/harness.jar!/harness/policy/policy.all", + "", null); + perm3 = new UnresolvedPermission("permission com.sun.jini.start.SharedActivationPolicyPermission", + "jar:file:/opt/src/river/trunk/qa/lib/harness.jar!/harness/policy/defaultgroup.policy", + "", null); + permissions = new ArrayList<Permission>(4); + permissions.add(perm0); + permissions.add(perm1); + permissions.add(perm2); + permissions.add(perm3); + PermissionGrantBuilder pgb = PermissionGrantBuilder.newBuilder(); + URI uri = null; + try { + uri = new URI("file:/opt/src/river/trunk/lib/group.jar"); + } catch (URISyntaxException ex) { + System.err.println(ex); + } + grant = pgb + .uri(uri) + .permissions(permissions.toArray(new Permission[4])) + .context(PermissionGrantBuilder.URI) + .build(); + } /** * Tests parsing of a sample policy from temporary file, validates returned @@ -95,7 +167,7 @@ public class DefaultPolicyParserTest ext tmp.delete(); } } - + // /** // * Test of segment method, of class DefaultPolicyParser. // */ @@ -124,6 +196,97 @@ public class DefaultPolicyParserTest ext // assertEquals(expResult, result); // } // + + /** + * Test of resolveGrant method, of class DefaultPolicyParser. + */ + @Test + public void testResolveGrant() throws Exception { + System.out.println("resolveGrant"); + KeyStore ks = null; + boolean resolve = true; + DefaultPolicyParser instance = new DefaultPolicyParser(); + PermissionGrant expResult = grant; + PermissionGrant result = instance.resolveGrant(ge, ks, system, resolve); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); + } + + /** + * Test of resolvePermission method, of class DefaultPolicyParser. + */ + @Test + public void testResolvePermission() throws Exception { + System.out.println("resolvePermission"); + KeyStore ks = null; + boolean resolve = true; + DefaultPolicyParser instance = new DefaultPolicyParser(); + Permission expResult = perm0; + Permission result = instance.resolvePermission(pe0, ge, ks, system, resolve); + assertEquals(expResult, result); + expResult = perm1; + result = instance.resolvePermission(pe1, ge, ks, system, resolve); + assertEquals(expResult, result); + expResult = perm2; + result = instance.resolvePermission(pe2, ge, ks, system, resolve); + assertEquals(expResult, result); + expResult = perm3; + result = instance.resolvePermission(pe3, ge, ks, system, resolve); + assertEquals(expResult, result); + // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); + } + +// /** +// * Test of resolveSigners method, of class DefaultPolicyParser. +// */ +// @Test +// public void testResolveSigners() throws Exception { +// System.out.println("resolveSigners"); +// KeyStore ks = null; +// String signers = ""; +// DefaultPolicyParser instance = new DefaultPolicyParser(); +// Certificate[] expResult = null; +// Certificate[] result = instance.resolveSigners(ks, signers); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } + +// /** +// * Test of getPrincipalByAlias method, of class DefaultPolicyParser. +// */ +// @Test +// public void testGetPrincipalByAlias() throws Exception { +// System.out.println("getPrincipalByAlias"); +// KeyStore ks = null; +// String alias = ""; +// DefaultPolicyParser instance = new DefaultPolicyParser(); +// Principal expResult = null; +// Principal result = instance.getPrincipalByAlias(ks, alias); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } +// +// /** +// * Test of initKeyStore method, of class DefaultPolicyParser. +// */ +// @Test +// public void testInitKeyStore() { +// System.out.println("initKeyStore"); +// List<KeystoreEntry> keystores = null; +// URL base = null; +// Properties system = null; +// boolean resolve = false; +// DefaultPolicyParser instance = new DefaultPolicyParser(); +// KeyStore expResult = null; +// KeyStore result = instance.initKeyStore(keystores, base, system, resolve); +// assertEquals(expResult, result); +// // TODO review the generated test code and remove the default call to fail. +// fail("The test case is a prototype."); +// } } class FakePrincipal implements Principal { Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/util/ReferenceCollectionTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/util/ReferenceCollectionTest.java?rev=1229137&r1=1229136&r2=1229137&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/util/ReferenceCollectionTest.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/util/ReferenceCollectionTest.java Mon Jan 9 13:12:52 2012 @@ -19,7 +19,6 @@ package org.apache.river.impl.util; import java.util.ArrayList; -import java.lang.ref.Reference; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; @@ -57,7 +56,7 @@ public class ReferenceCollectionTest { @Before public void setUp() { - instance = new ReferenceCollection<String>(new ArrayList<Referrer<String>>(), Ref.WEAK_IDENTITY); + instance = new ReferenceCollection<String>(new ArrayList<Referrer<String>>(), Ref.WEAK_IDENTITY, false); instance.add(truck); instance.add(shovel); instance.add(grader);
