You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by ad...@apache.org on 2010/05/26 20:34:49 UTC
svn commit: r948527 [22/38] - in /incubator/shiro:
branches/shiro-root-1.0.x/ branches/shiro-root-1.0.x/all/
branches/shiro-root-1.0.x/core/src/main/java/org/apache/shiro/
branches/shiro-root-1.0.x/core/src/main/java/org/apache/shiro/aop/
branches/shir...
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/Ini.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/Ini.java?rev=948527&r1=948526&r2=948527&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/Ini.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/Ini.java Wed May 26 18:34:28 2010
@@ -1,568 +1,568 @@
-/*
- * 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.shiro.config;
-
-import org.apache.shiro.io.ResourceUtils;
-import org.apache.shiro.util.CollectionUtils;
-import org.apache.shiro.util.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A class representing the <a href="http://en.wikipedia.org/wiki/INI_file">INI</a> text configuration format.
- * <p/>
- * An Ini instance is a map of {@link Ini.Section Section}s, keyed by section name. Each
- * {@code Section} is itself a map of {@code String} name/value pairs. Name/value pairs are guaranteed to be unique
- * within each {@code Section} only - not across the entire {@code Ini} instance.
- *
- * @author The Apache Shiro Project (shiro-dev@incubator.apache.org)
- * @since 1.0
- */
-public class Ini implements Map<String, Ini.Section> {
-
- private static transient final Logger log = LoggerFactory.getLogger(Ini.class);
-
- public static final String DEFAULT_SECTION_NAME = ""; //empty string means the first unnamed section
- public static final String DEFAULT_CHARSET_NAME = "ISO-8859-1";
-
- public static final String COMMENT_POUND = "#";
- public static final String COMMENT_SEMICOLON = ";";
- public static final String SECTION_PREFIX = "[";
- public static final String SECTION_SUFFIX = "]";
-
- private final Map<String, Section> sections;
-
- /**
- * Creates a new empty {@code Ini} instance.
- */
- public Ini() {
- this.sections = new LinkedHashMap<String, Section>();
- }
-
- /**
- * Creates a new {@code Ini} instance with the specified defaults.
- *
- * @param defaults the default sections and/or key-value pairs to copy into the new instance.
- */
- public Ini(Ini defaults) {
- this();
- if (defaults == null) {
- throw new NullPointerException("Defaults cannot be null.");
- }
- for (Section section : defaults.getSections()) {
- Section copy = new Section(section);
- this.sections.put(section.getName(), copy);
- }
- }
-
- /**
- * Returns {@code true} if no sections have been configured, or if there are sections, but the sections themselves
- * are all empty, {@code false} otherwise.
- *
- * @return {@code true} if no sections have been configured, or if there are sections, but the sections themselves
- * are all empty, {@code false} otherwise.
- */
- public boolean isEmpty() {
- Collection<Section> sections = this.sections.values();
- if (!sections.isEmpty()) {
- for (Section section : sections) {
- if (!section.isEmpty()) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Returns the names of all sections managed by this {@code Ini} instance or an empty collection if there are
- * no sections.
- *
- * @return the names of all sections managed by this {@code Ini} instance or an empty collection if there are
- * no sections.
- */
- public Set<String> getSectionNames() {
- return Collections.unmodifiableSet(sections.keySet());
- }
-
- /**
- * Returns the sections managed by this {@code Ini} instance or an empty collection if there are
- * no sections.
- *
- * @return the sections managed by this {@code Ini} instance or an empty collection if there are
- * no sections.
- */
- public Collection<Section> getSections() {
- return Collections.unmodifiableCollection(sections.values());
- }
-
- /**
- * Returns the {@link Section} with the given name or {@code null} if no section with that name exists.
- *
- * @param sectionName the name of the section to retrieve.
- * @return the {@link Section} with the given name or {@code null} if no section with that name exists.
- */
- public Section getSection(String sectionName) {
- String name = cleanName(sectionName);
- return sections.get(name);
- }
-
- /**
- * Ensures a section with the specified name exists, adding a new one if it does not yet exist.
- *
- * @param sectionName the name of the section to ensure existence
- * @return the section created if it did not yet exist, or the existing Section that already existed.
- */
- public Section addSection(String sectionName) {
- String name = cleanName(sectionName);
- Section section = getSection(name);
- if (section == null) {
- section = new Section(name);
- this.sections.put(name, section);
- }
- return section;
- }
-
- /**
- * Removes the section with the specified name and returns it, or {@code null} if the section did not exist.
- *
- * @param sectionName the name of the section to remove.
- * @return the section with the specified name or {@code null} if the section did not exist.
- */
- public Section removeSection(String sectionName) {
- String name = cleanName(sectionName);
- return this.sections.remove(name);
- }
-
- private static String cleanName(String sectionName) {
- String name = StringUtils.clean(sectionName);
- if (name == null) {
- log.trace("Specified name was null or empty. Defaulting to the default section (name = \"\")");
- name = DEFAULT_SECTION_NAME;
- }
- return name;
- }
-
- /**
- * Sets a name/value pair for the section with the given {@code sectionName}. If the section does not yet exist,
- * it will be created. If the {@code sectionName} is null or empty, the name/value pair will be placed in the
- * default (unnamed, empty string) section.
- *
- * @param sectionName the name of the section to add the name/value pair
- * @param propertyName the name of the property to add
- * @param propertyValue the property value
- */
- public void setSectionProperty(String sectionName, String propertyName, String propertyValue) {
- String name = cleanName(sectionName);
- Section section = getSection(name);
- if (section == null) {
- section = addSection(name);
- }
- section.put(propertyName, propertyValue);
- }
-
- /**
- * Returns the value of the specified section property, or {@code null} if the section or property do not exist.
- *
- * @param sectionName the name of the section to retrieve to acquire the property value
- * @param propertyName the name of the section property for which to return the value
- * @return the value of the specified section property, or {@code null} if the section or property do not exist.
- */
- public String getSectionProperty(String sectionName, String propertyName) {
- Section section = getSection(sectionName);
- return section != null ? section.get(propertyName) : null;
- }
-
- /**
- * Returns the value of the specified section property, or the {@code defaultValue} if the section or
- * property do not exist.
- *
- * @param sectionName the name of the section to add the name/value pair
- * @param propertyName the name of the property to add
- * @param defaultValue the default value to return if the section or property do not exist.
- * @return the value of the specified section property, or the {@code defaultValue} if the section or
- * property do not exist.
- */
- public String getSectionProperty(String sectionName, String propertyName, String defaultValue) {
- String value = getSectionProperty(sectionName, propertyName);
- return value != null ? value : defaultValue;
- }
-
- /**
- * Creates a new {@code Ini} instance loaded with the INI-formatted data in the resource at the given path. The
- * resource path may be any value interpretable by the
- * {@link ResourceUtils#getInputStreamForPath(String) ResourceUtils.getInputStreamForPath} method.
- *
- * @param resourcePath the resource location of the INI data to load when creating the {@code Ini} instance.
- * @return a new {@code Ini} instance loaded with the INI-formatted data in the resource at the given path.
- * @throws ConfigurationException if the path cannot be loaded into an {@code Ini} instance.
- */
- public static Ini fromResourcePath(String resourcePath) throws ConfigurationException {
- if (!StringUtils.hasLength(resourcePath)) {
- throw new IllegalArgumentException("Resource Path argument cannot be null or empty.");
- }
- Ini ini = new Ini();
- ini.loadFromPath(resourcePath);
- return ini;
- }
-
- /**
- * Loads data from the specified resource path into this current {@code Ini} instance. The
- * resource path may be any value interpretable by the
- * {@link ResourceUtils#getInputStreamForPath(String) ResourceUtils.getInputStreamForPath} method.
- *
- * @param resourcePath the resource location of the INI data to load into this instance.
- * @throws ConfigurationException if the path cannot be loaded
- */
- public void loadFromPath(String resourcePath) throws ConfigurationException {
- InputStream is;
- try {
- is = ResourceUtils.getInputStreamForPath(resourcePath);
- } catch (IOException e) {
- throw new ConfigurationException(e);
- }
- load(is);
- }
-
- /**
- * Loads the specified raw INI-formatted text into this instance.
- *
- * @param iniConfig the raw INI-formatted text to load into this instance.
- * @throws ConfigurationException if the text cannot be loaded
- */
- public void load(String iniConfig) throws ConfigurationException {
- load(new Scanner(iniConfig));
- }
-
- /**
- * Loads the INI-formatted text backed by the given InputStream into this instance. This implementation will
- * close the input stream after it has finished loading.
- *
- * @param is the {@code InputStream} from which to read the INI-formatted text
- * @throws ConfigurationException if unable
- */
- public void load(InputStream is) throws ConfigurationException {
- if (is == null) {
- throw new NullPointerException("InputStream argument cannot be null.");
- }
- InputStreamReader isr;
- try {
- isr = new InputStreamReader(is, DEFAULT_CHARSET_NAME);
- } catch (UnsupportedEncodingException e) {
- throw new ConfigurationException(e);
- }
- load(isr);
- }
-
- /**
- * Loads the INI-formatted text backed by the given Reader into this instance. This implementation will close the
- * reader after it has finished loading.
- *
- * @param reader the {@code Reader} from which to read the INI-formatted text
- */
- public void load(Reader reader) {
- Scanner scanner = new Scanner(reader);
- try {
- load(scanner);
- } finally {
- try {
- scanner.close();
- } catch (Exception e) {
- log.debug("Unable to cleanly close the InputStream scanner. Non-critical - ignoring.", e);
- }
- }
- }
-
- private static InputStream toInputStream(String content) {
- byte[] bytes;
- try {
- bytes = content.getBytes(DEFAULT_CHARSET_NAME);
- } catch (UnsupportedEncodingException e) {
- throw new ConfigurationException(e);
- }
- return new ByteArrayInputStream(bytes);
- }
-
- private static Properties toProps(String content) {
- InputStream is = toInputStream(content);
- Properties props = new Properties();
- try {
- props.load(is);
- } catch (IOException e) {
- throw new ConfigurationException(e);
- }
- return props;
- }
-
- private void addSection(String name, StringBuffer content) {
- if (content.length() > 0) {
- String contentString = content.toString();
- String cleaned = StringUtils.clean(contentString);
- if (cleaned != null) {
- Properties props = toProps(contentString);
- if (!props.isEmpty()) {
- sections.put(name, new Section(name, props));
- }
- }
- }
- }
-
- /**
- * Loads the INI-formatted text backed by the given Scanner. This implementation will close the
- * scanner after it has finished loading.
- *
- * @param scanner the {@code Scanner} from which to read the INI-formatted text
- */
- public void load(Scanner scanner) {
-
- String sectionName = DEFAULT_SECTION_NAME;
- StringBuffer sectionContent = new StringBuffer();
-
- while (scanner.hasNextLine()) {
-
- String rawLine = scanner.nextLine();
- String line = StringUtils.clean(rawLine);
-
- if (line == null || line.startsWith(COMMENT_POUND) || line.startsWith(COMMENT_SEMICOLON)) {
- //skip empty lines and comments:
- continue;
- }
-
- String newSectionName = getSectionName(line);
- if (newSectionName != null) {
- //found a new section - convert the currently buffered one into a Section object
- addSection(sectionName, sectionContent);
-
- //reset the buffer for the new section:
- sectionContent = new StringBuffer();
-
- sectionName = newSectionName;
-
- if (log.isDebugEnabled()) {
- log.debug("Parsing " + SECTION_PREFIX + sectionName + SECTION_SUFFIX);
- }
- } else {
- //normal line - add it to the existing content buffer:
- sectionContent.append(rawLine).append("\n");
- }
- }
-
- //finish any remaining buffered content:
- addSection(sectionName, sectionContent);
- }
-
- protected static boolean isSectionHeader(String line) {
- String s = StringUtils.clean(line);
- return s != null && s.startsWith(SECTION_PREFIX) && s.endsWith(SECTION_SUFFIX);
- }
-
- protected static String getSectionName(String line) {
- String s = StringUtils.clean(line);
- if (isSectionHeader(s)) {
- return cleanName(s.substring(1, s.length() - 1));
- }
- return null;
- }
-
- public boolean equals(Object obj) {
- if (obj instanceof Ini) {
- Ini ini = (Ini) obj;
- return this.sections.equals(ini.sections);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return this.sections.hashCode();
- }
-
- public String toString() {
- if (CollectionUtils.isEmpty(this.sections)) {
- return "<empty INI>";
- } else {
- StringBuilder sb = new StringBuilder("sections=");
- int i = 0;
- for (Ini.Section section : this.sections.values()) {
- if (i > 0) {
- sb.append(",");
- }
- sb.append(section.toString());
- i++;
- }
- return sb.toString();
- }
- }
-
- public int size() {
- return this.sections.size();
- }
-
- public boolean containsKey(Object key) {
- return this.sections.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return this.sections.containsValue(value);
- }
-
- public Section get(Object key) {
- return this.sections.get(key);
- }
-
- public Section put(String key, Section value) {
- return this.sections.put(key, value);
- }
-
- public Section remove(Object key) {
- return this.sections.remove(key);
- }
-
- public void putAll(Map<? extends String, ? extends Section> m) {
- this.sections.putAll(m);
- }
-
- public void clear() {
- this.sections.clear();
- }
-
- public Set<String> keySet() {
- return Collections.unmodifiableSet(this.sections.keySet());
- }
-
- public Collection<Section> values() {
- return Collections.unmodifiableCollection(this.sections.values());
- }
-
- public Set<Entry<String, Section>> entrySet() {
- return Collections.unmodifiableSet(this.sections.entrySet());
- }
-
- /**
- * An {@code Ini.Section} is String-key-to-String-value Map, identifiable by a
- * {@link #getName() name} unique within an {@link Ini} instance.
- */
- public class Section implements Map<String, String> {
- private final String name;
- private final Map<String, String> props;
-
- private Section(String name) {
- if (name == null) {
- throw new NullPointerException("name");
- }
- this.name = name;
- this.props = new LinkedHashMap<String, String>();
- }
-
- private Section(String name, Properties props) {
- this(name);
- Enumeration propNames = props.propertyNames();
- while (propNames != null && propNames.hasMoreElements()) {
- String key = propNames.nextElement().toString();
- String value = props.getProperty(key);
- if (value != null) {
- this.props.put(key, value.trim());
- }
- }
- }
-
- private Section(Section defaults) {
- this(defaults.getName());
- putAll(defaults.props);
- }
-
- public String getName() {
- return this.name;
- }
-
- public void clear() {
- this.props.clear();
- }
-
- public boolean containsKey(Object key) {
- return this.props.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return this.props.containsValue(value);
- }
-
- public Set<Entry<String, String>> entrySet() {
- return this.props.entrySet();
- }
-
- public String get(Object key) {
- return this.props.get(key);
- }
-
- public boolean isEmpty() {
- return this.props.isEmpty();
- }
-
- public Set<String> keySet() {
- return this.props.keySet();
- }
-
- public String put(String key, String value) {
- return this.props.put(key, value);
- }
-
- public void putAll(Map<? extends String, ? extends String> m) {
- this.props.putAll(m);
- }
-
- public String remove(Object key) {
- return this.props.remove(key);
- }
-
- public int size() {
- return this.props.size();
- }
-
- public Collection<String> values() {
- return this.props.values();
- }
-
- public String toString() {
- String name = getName();
- if (DEFAULT_SECTION_NAME.equals(name)) {
- return "<default>";
- }
- return name;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Section) {
- Section other = (Section) obj;
- return getName().equals(other.getName()) && this.props.equals(other.props);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return this.name.hashCode() * 31 + this.props.hashCode();
- }
- }
-
-}
+/*
+ * 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.shiro.config;
+
+import org.apache.shiro.io.ResourceUtils;
+import org.apache.shiro.util.CollectionUtils;
+import org.apache.shiro.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A class representing the <a href="http://en.wikipedia.org/wiki/INI_file">INI</a> text configuration format.
+ * <p/>
+ * An Ini instance is a map of {@link Ini.Section Section}s, keyed by section name. Each
+ * {@code Section} is itself a map of {@code String} name/value pairs. Name/value pairs are guaranteed to be unique
+ * within each {@code Section} only - not across the entire {@code Ini} instance.
+ *
+ * @author The Apache Shiro Project (shiro-dev@incubator.apache.org)
+ * @since 1.0
+ */
+public class Ini implements Map<String, Ini.Section> {
+
+ private static transient final Logger log = LoggerFactory.getLogger(Ini.class);
+
+ public static final String DEFAULT_SECTION_NAME = ""; //empty string means the first unnamed section
+ public static final String DEFAULT_CHARSET_NAME = "ISO-8859-1";
+
+ public static final String COMMENT_POUND = "#";
+ public static final String COMMENT_SEMICOLON = ";";
+ public static final String SECTION_PREFIX = "[";
+ public static final String SECTION_SUFFIX = "]";
+
+ private final Map<String, Section> sections;
+
+ /**
+ * Creates a new empty {@code Ini} instance.
+ */
+ public Ini() {
+ this.sections = new LinkedHashMap<String, Section>();
+ }
+
+ /**
+ * Creates a new {@code Ini} instance with the specified defaults.
+ *
+ * @param defaults the default sections and/or key-value pairs to copy into the new instance.
+ */
+ public Ini(Ini defaults) {
+ this();
+ if (defaults == null) {
+ throw new NullPointerException("Defaults cannot be null.");
+ }
+ for (Section section : defaults.getSections()) {
+ Section copy = new Section(section);
+ this.sections.put(section.getName(), copy);
+ }
+ }
+
+ /**
+ * Returns {@code true} if no sections have been configured, or if there are sections, but the sections themselves
+ * are all empty, {@code false} otherwise.
+ *
+ * @return {@code true} if no sections have been configured, or if there are sections, but the sections themselves
+ * are all empty, {@code false} otherwise.
+ */
+ public boolean isEmpty() {
+ Collection<Section> sections = this.sections.values();
+ if (!sections.isEmpty()) {
+ for (Section section : sections) {
+ if (!section.isEmpty()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the names of all sections managed by this {@code Ini} instance or an empty collection if there are
+ * no sections.
+ *
+ * @return the names of all sections managed by this {@code Ini} instance or an empty collection if there are
+ * no sections.
+ */
+ public Set<String> getSectionNames() {
+ return Collections.unmodifiableSet(sections.keySet());
+ }
+
+ /**
+ * Returns the sections managed by this {@code Ini} instance or an empty collection if there are
+ * no sections.
+ *
+ * @return the sections managed by this {@code Ini} instance or an empty collection if there are
+ * no sections.
+ */
+ public Collection<Section> getSections() {
+ return Collections.unmodifiableCollection(sections.values());
+ }
+
+ /**
+ * Returns the {@link Section} with the given name or {@code null} if no section with that name exists.
+ *
+ * @param sectionName the name of the section to retrieve.
+ * @return the {@link Section} with the given name or {@code null} if no section with that name exists.
+ */
+ public Section getSection(String sectionName) {
+ String name = cleanName(sectionName);
+ return sections.get(name);
+ }
+
+ /**
+ * Ensures a section with the specified name exists, adding a new one if it does not yet exist.
+ *
+ * @param sectionName the name of the section to ensure existence
+ * @return the section created if it did not yet exist, or the existing Section that already existed.
+ */
+ public Section addSection(String sectionName) {
+ String name = cleanName(sectionName);
+ Section section = getSection(name);
+ if (section == null) {
+ section = new Section(name);
+ this.sections.put(name, section);
+ }
+ return section;
+ }
+
+ /**
+ * Removes the section with the specified name and returns it, or {@code null} if the section did not exist.
+ *
+ * @param sectionName the name of the section to remove.
+ * @return the section with the specified name or {@code null} if the section did not exist.
+ */
+ public Section removeSection(String sectionName) {
+ String name = cleanName(sectionName);
+ return this.sections.remove(name);
+ }
+
+ private static String cleanName(String sectionName) {
+ String name = StringUtils.clean(sectionName);
+ if (name == null) {
+ log.trace("Specified name was null or empty. Defaulting to the default section (name = \"\")");
+ name = DEFAULT_SECTION_NAME;
+ }
+ return name;
+ }
+
+ /**
+ * Sets a name/value pair for the section with the given {@code sectionName}. If the section does not yet exist,
+ * it will be created. If the {@code sectionName} is null or empty, the name/value pair will be placed in the
+ * default (unnamed, empty string) section.
+ *
+ * @param sectionName the name of the section to add the name/value pair
+ * @param propertyName the name of the property to add
+ * @param propertyValue the property value
+ */
+ public void setSectionProperty(String sectionName, String propertyName, String propertyValue) {
+ String name = cleanName(sectionName);
+ Section section = getSection(name);
+ if (section == null) {
+ section = addSection(name);
+ }
+ section.put(propertyName, propertyValue);
+ }
+
+ /**
+ * Returns the value of the specified section property, or {@code null} if the section or property do not exist.
+ *
+ * @param sectionName the name of the section to retrieve to acquire the property value
+ * @param propertyName the name of the section property for which to return the value
+ * @return the value of the specified section property, or {@code null} if the section or property do not exist.
+ */
+ public String getSectionProperty(String sectionName, String propertyName) {
+ Section section = getSection(sectionName);
+ return section != null ? section.get(propertyName) : null;
+ }
+
+ /**
+ * Returns the value of the specified section property, or the {@code defaultValue} if the section or
+ * property do not exist.
+ *
+ * @param sectionName the name of the section to add the name/value pair
+ * @param propertyName the name of the property to add
+ * @param defaultValue the default value to return if the section or property do not exist.
+ * @return the value of the specified section property, or the {@code defaultValue} if the section or
+ * property do not exist.
+ */
+ public String getSectionProperty(String sectionName, String propertyName, String defaultValue) {
+ String value = getSectionProperty(sectionName, propertyName);
+ return value != null ? value : defaultValue;
+ }
+
+ /**
+ * Creates a new {@code Ini} instance loaded with the INI-formatted data in the resource at the given path. The
+ * resource path may be any value interpretable by the
+ * {@link ResourceUtils#getInputStreamForPath(String) ResourceUtils.getInputStreamForPath} method.
+ *
+ * @param resourcePath the resource location of the INI data to load when creating the {@code Ini} instance.
+ * @return a new {@code Ini} instance loaded with the INI-formatted data in the resource at the given path.
+ * @throws ConfigurationException if the path cannot be loaded into an {@code Ini} instance.
+ */
+ public static Ini fromResourcePath(String resourcePath) throws ConfigurationException {
+ if (!StringUtils.hasLength(resourcePath)) {
+ throw new IllegalArgumentException("Resource Path argument cannot be null or empty.");
+ }
+ Ini ini = new Ini();
+ ini.loadFromPath(resourcePath);
+ return ini;
+ }
+
+ /**
+ * Loads data from the specified resource path into this current {@code Ini} instance. The
+ * resource path may be any value interpretable by the
+ * {@link ResourceUtils#getInputStreamForPath(String) ResourceUtils.getInputStreamForPath} method.
+ *
+ * @param resourcePath the resource location of the INI data to load into this instance.
+ * @throws ConfigurationException if the path cannot be loaded
+ */
+ public void loadFromPath(String resourcePath) throws ConfigurationException {
+ InputStream is;
+ try {
+ is = ResourceUtils.getInputStreamForPath(resourcePath);
+ } catch (IOException e) {
+ throw new ConfigurationException(e);
+ }
+ load(is);
+ }
+
+ /**
+ * Loads the specified raw INI-formatted text into this instance.
+ *
+ * @param iniConfig the raw INI-formatted text to load into this instance.
+ * @throws ConfigurationException if the text cannot be loaded
+ */
+ public void load(String iniConfig) throws ConfigurationException {
+ load(new Scanner(iniConfig));
+ }
+
+ /**
+ * Loads the INI-formatted text backed by the given InputStream into this instance. This implementation will
+ * close the input stream after it has finished loading.
+ *
+ * @param is the {@code InputStream} from which to read the INI-formatted text
+ * @throws ConfigurationException if unable
+ */
+ public void load(InputStream is) throws ConfigurationException {
+ if (is == null) {
+ throw new NullPointerException("InputStream argument cannot be null.");
+ }
+ InputStreamReader isr;
+ try {
+ isr = new InputStreamReader(is, DEFAULT_CHARSET_NAME);
+ } catch (UnsupportedEncodingException e) {
+ throw new ConfigurationException(e);
+ }
+ load(isr);
+ }
+
+ /**
+ * Loads the INI-formatted text backed by the given Reader into this instance. This implementation will close the
+ * reader after it has finished loading.
+ *
+ * @param reader the {@code Reader} from which to read the INI-formatted text
+ */
+ public void load(Reader reader) {
+ Scanner scanner = new Scanner(reader);
+ try {
+ load(scanner);
+ } finally {
+ try {
+ scanner.close();
+ } catch (Exception e) {
+ log.debug("Unable to cleanly close the InputStream scanner. Non-critical - ignoring.", e);
+ }
+ }
+ }
+
+ private static InputStream toInputStream(String content) {
+ byte[] bytes;
+ try {
+ bytes = content.getBytes(DEFAULT_CHARSET_NAME);
+ } catch (UnsupportedEncodingException e) {
+ throw new ConfigurationException(e);
+ }
+ return new ByteArrayInputStream(bytes);
+ }
+
+ private static Properties toProps(String content) {
+ InputStream is = toInputStream(content);
+ Properties props = new Properties();
+ try {
+ props.load(is);
+ } catch (IOException e) {
+ throw new ConfigurationException(e);
+ }
+ return props;
+ }
+
+ private void addSection(String name, StringBuffer content) {
+ if (content.length() > 0) {
+ String contentString = content.toString();
+ String cleaned = StringUtils.clean(contentString);
+ if (cleaned != null) {
+ Properties props = toProps(contentString);
+ if (!props.isEmpty()) {
+ sections.put(name, new Section(name, props));
+ }
+ }
+ }
+ }
+
+ /**
+ * Loads the INI-formatted text backed by the given Scanner. This implementation will close the
+ * scanner after it has finished loading.
+ *
+ * @param scanner the {@code Scanner} from which to read the INI-formatted text
+ */
+ public void load(Scanner scanner) {
+
+ String sectionName = DEFAULT_SECTION_NAME;
+ StringBuffer sectionContent = new StringBuffer();
+
+ while (scanner.hasNextLine()) {
+
+ String rawLine = scanner.nextLine();
+ String line = StringUtils.clean(rawLine);
+
+ if (line == null || line.startsWith(COMMENT_POUND) || line.startsWith(COMMENT_SEMICOLON)) {
+ //skip empty lines and comments:
+ continue;
+ }
+
+ String newSectionName = getSectionName(line);
+ if (newSectionName != null) {
+ //found a new section - convert the currently buffered one into a Section object
+ addSection(sectionName, sectionContent);
+
+ //reset the buffer for the new section:
+ sectionContent = new StringBuffer();
+
+ sectionName = newSectionName;
+
+ if (log.isDebugEnabled()) {
+ log.debug("Parsing " + SECTION_PREFIX + sectionName + SECTION_SUFFIX);
+ }
+ } else {
+ //normal line - add it to the existing content buffer:
+ sectionContent.append(rawLine).append("\n");
+ }
+ }
+
+ //finish any remaining buffered content:
+ addSection(sectionName, sectionContent);
+ }
+
+ protected static boolean isSectionHeader(String line) {
+ String s = StringUtils.clean(line);
+ return s != null && s.startsWith(SECTION_PREFIX) && s.endsWith(SECTION_SUFFIX);
+ }
+
+ protected static String getSectionName(String line) {
+ String s = StringUtils.clean(line);
+ if (isSectionHeader(s)) {
+ return cleanName(s.substring(1, s.length() - 1));
+ }
+ return null;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof Ini) {
+ Ini ini = (Ini) obj;
+ return this.sections.equals(ini.sections);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.sections.hashCode();
+ }
+
+ public String toString() {
+ if (CollectionUtils.isEmpty(this.sections)) {
+ return "<empty INI>";
+ } else {
+ StringBuilder sb = new StringBuilder("sections=");
+ int i = 0;
+ for (Ini.Section section : this.sections.values()) {
+ if (i > 0) {
+ sb.append(",");
+ }
+ sb.append(section.toString());
+ i++;
+ }
+ return sb.toString();
+ }
+ }
+
+ public int size() {
+ return this.sections.size();
+ }
+
+ public boolean containsKey(Object key) {
+ return this.sections.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return this.sections.containsValue(value);
+ }
+
+ public Section get(Object key) {
+ return this.sections.get(key);
+ }
+
+ public Section put(String key, Section value) {
+ return this.sections.put(key, value);
+ }
+
+ public Section remove(Object key) {
+ return this.sections.remove(key);
+ }
+
+ public void putAll(Map<? extends String, ? extends Section> m) {
+ this.sections.putAll(m);
+ }
+
+ public void clear() {
+ this.sections.clear();
+ }
+
+ public Set<String> keySet() {
+ return Collections.unmodifiableSet(this.sections.keySet());
+ }
+
+ public Collection<Section> values() {
+ return Collections.unmodifiableCollection(this.sections.values());
+ }
+
+ public Set<Entry<String, Section>> entrySet() {
+ return Collections.unmodifiableSet(this.sections.entrySet());
+ }
+
+ /**
+ * An {@code Ini.Section} is String-key-to-String-value Map, identifiable by a
+ * {@link #getName() name} unique within an {@link Ini} instance.
+ */
+ public class Section implements Map<String, String> {
+ private final String name;
+ private final Map<String, String> props;
+
+ private Section(String name) {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+ this.name = name;
+ this.props = new LinkedHashMap<String, String>();
+ }
+
+ private Section(String name, Properties props) {
+ this(name);
+ Enumeration propNames = props.propertyNames();
+ while (propNames != null && propNames.hasMoreElements()) {
+ String key = propNames.nextElement().toString();
+ String value = props.getProperty(key);
+ if (value != null) {
+ this.props.put(key, value.trim());
+ }
+ }
+ }
+
+ private Section(Section defaults) {
+ this(defaults.getName());
+ putAll(defaults.props);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void clear() {
+ this.props.clear();
+ }
+
+ public boolean containsKey(Object key) {
+ return this.props.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return this.props.containsValue(value);
+ }
+
+ public Set<Entry<String, String>> entrySet() {
+ return this.props.entrySet();
+ }
+
+ public String get(Object key) {
+ return this.props.get(key);
+ }
+
+ public boolean isEmpty() {
+ return this.props.isEmpty();
+ }
+
+ public Set<String> keySet() {
+ return this.props.keySet();
+ }
+
+ public String put(String key, String value) {
+ return this.props.put(key, value);
+ }
+
+ public void putAll(Map<? extends String, ? extends String> m) {
+ this.props.putAll(m);
+ }
+
+ public String remove(Object key) {
+ return this.props.remove(key);
+ }
+
+ public int size() {
+ return this.props.size();
+ }
+
+ public Collection<String> values() {
+ return this.props.values();
+ }
+
+ public String toString() {
+ String name = getName();
+ if (DEFAULT_SECTION_NAME.equals(name)) {
+ return "<default>";
+ }
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Section) {
+ Section other = (Section) obj;
+ return getName().equals(other.getName()) && this.props.equals(other.props);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.name.hashCode() * 31 + this.props.hashCode();
+ }
+ }
+
+}
Propchange: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/Ini.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java?rev=948527&r1=948526&r2=948527&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java Wed May 26 18:34:28 2010
@@ -1,138 +1,138 @@
-/*
- * 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.shiro.config;
-
-import org.apache.shiro.io.ResourceUtils;
-import org.apache.shiro.util.AbstractFactory;
-import org.apache.shiro.util.CollectionUtils;
-import org.apache.shiro.util.Factory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Base support class for {@link Factory} implementations that generate their instance(s) based on
- * {@link Ini} configuration.
- *
- * @author The Apache Shiro Project (shiro-dev@incubator.apache.org)
- * @since 1.0
- */
-public abstract class IniFactorySupport<T> extends AbstractFactory<T> {
-
- public static final String DEFAULT_INI_RESOURCE_PATH = "classpath:shiro.ini";
-
- private static transient final Logger log = LoggerFactory.getLogger(IniFactorySupport.class);
-
- private Ini ini;
-
- protected IniFactorySupport() {
- }
-
- protected IniFactorySupport(Ini ini) {
- this.ini = ini;
- }
-
- public Ini getIni() {
- return ini;
- }
-
- public void setIni(Ini ini) {
- this.ini = ini;
- }
-
- /**
- * Returns a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
- * the file does not exist.
- *
- * @return a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
- * the file does not exist.
- */
- public static Ini loadDefaultClassPathIni() {
- Ini ini = null;
- if (ResourceUtils.resourceExists(DEFAULT_INI_RESOURCE_PATH)) {
- log.debug("Found shiro.ini at the root of the classpath.");
- ini = new Ini();
- ini.loadFromPath(DEFAULT_INI_RESOURCE_PATH);
- if (CollectionUtils.isEmpty(ini)) {
- log.warn("shiro.ini found at the root of the classpath, but it did not contain any data.");
- }
- }
- return ini;
- }
-
- /**
- * Tries to resolve the Ini instance to use for configuration. This implementation functions as follows:
- * <ol>
- * <li>The {@code Ini} instance returned from {@link #getIni()} will be returned if it is not null or empty.</li>
- * <li>If {@link #getIni()} is {@code null} or empty, this implementation will attempt to find and load the
- * {@link #loadDefaultClassPathIni() default class path Ini}.</li>
- * <li>If neither of the two attempts above returns an instance, {@code null} is returned</li>
- * </ol>
- *
- * @return the Ini instance to use for configuration.
- */
- protected Ini resolveIni() {
- Ini ini = getIni();
- if (CollectionUtils.isEmpty(ini)) {
- log.debug("Null or empty Ini instance. Falling back to the default {} file.", DEFAULT_INI_RESOURCE_PATH);
- ini = loadDefaultClassPathIni();
- }
- return ini;
- }
-
- /**
- * Creates a new object instance by using a configured INI source. This implementation functions as follows:
- * <ol>
- * <li>{@link #resolveIni() Resolve} the {@code Ini} source to use for configuration.</li>
- * <li>If there was no resolved Ini source, create and return a simple default instance via the
- * {@link #createDefaultInstance()} method.</li>
- * </ol>
- *
- * @return a new {@code SecurityManager} instance by using a configured INI source.
- */
- public T createInstance() {
- Ini ini = resolveIni();
-
- T instance;
-
- if (CollectionUtils.isEmpty(ini)) {
- log.debug("No populated Ini available. Creating a default instance.");
- instance = createDefaultInstance();
- if (instance == null) {
- String msg = getClass().getName() + " implementation did not return a default instance in " +
- "the event of a null/empty Ini configuration. This is required to support the " +
- "Factory interface. Please check your implementation.";
- throw new IllegalStateException(msg);
- }
- } else {
- log.debug("Creating instance from Ini [" + ini + "]");
- instance = createInstance(ini);
- if (instance == null) {
- String msg = getClass().getName() + " implementation did not return a constructed instance from " +
- "the createInstance(Ini) method implementation.";
- throw new IllegalStateException(msg);
- }
- }
-
- return instance;
- }
-
- protected abstract T createInstance(Ini ini);
-
- protected abstract T createDefaultInstance();
-}
+/*
+ * 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.shiro.config;
+
+import org.apache.shiro.io.ResourceUtils;
+import org.apache.shiro.util.AbstractFactory;
+import org.apache.shiro.util.CollectionUtils;
+import org.apache.shiro.util.Factory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base support class for {@link Factory} implementations that generate their instance(s) based on
+ * {@link Ini} configuration.
+ *
+ * @author The Apache Shiro Project (shiro-dev@incubator.apache.org)
+ * @since 1.0
+ */
+public abstract class IniFactorySupport<T> extends AbstractFactory<T> {
+
+ public static final String DEFAULT_INI_RESOURCE_PATH = "classpath:shiro.ini";
+
+ private static transient final Logger log = LoggerFactory.getLogger(IniFactorySupport.class);
+
+ private Ini ini;
+
+ protected IniFactorySupport() {
+ }
+
+ protected IniFactorySupport(Ini ini) {
+ this.ini = ini;
+ }
+
+ public Ini getIni() {
+ return ini;
+ }
+
+ public void setIni(Ini ini) {
+ this.ini = ini;
+ }
+
+ /**
+ * Returns a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
+ * the file does not exist.
+ *
+ * @return a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
+ * the file does not exist.
+ */
+ public static Ini loadDefaultClassPathIni() {
+ Ini ini = null;
+ if (ResourceUtils.resourceExists(DEFAULT_INI_RESOURCE_PATH)) {
+ log.debug("Found shiro.ini at the root of the classpath.");
+ ini = new Ini();
+ ini.loadFromPath(DEFAULT_INI_RESOURCE_PATH);
+ if (CollectionUtils.isEmpty(ini)) {
+ log.warn("shiro.ini found at the root of the classpath, but it did not contain any data.");
+ }
+ }
+ return ini;
+ }
+
+ /**
+ * Tries to resolve the Ini instance to use for configuration. This implementation functions as follows:
+ * <ol>
+ * <li>The {@code Ini} instance returned from {@link #getIni()} will be returned if it is not null or empty.</li>
+ * <li>If {@link #getIni()} is {@code null} or empty, this implementation will attempt to find and load the
+ * {@link #loadDefaultClassPathIni() default class path Ini}.</li>
+ * <li>If neither of the two attempts above returns an instance, {@code null} is returned</li>
+ * </ol>
+ *
+ * @return the Ini instance to use for configuration.
+ */
+ protected Ini resolveIni() {
+ Ini ini = getIni();
+ if (CollectionUtils.isEmpty(ini)) {
+ log.debug("Null or empty Ini instance. Falling back to the default {} file.", DEFAULT_INI_RESOURCE_PATH);
+ ini = loadDefaultClassPathIni();
+ }
+ return ini;
+ }
+
+ /**
+ * Creates a new object instance by using a configured INI source. This implementation functions as follows:
+ * <ol>
+ * <li>{@link #resolveIni() Resolve} the {@code Ini} source to use for configuration.</li>
+ * <li>If there was no resolved Ini source, create and return a simple default instance via the
+ * {@link #createDefaultInstance()} method.</li>
+ * </ol>
+ *
+ * @return a new {@code SecurityManager} instance by using a configured INI source.
+ */
+ public T createInstance() {
+ Ini ini = resolveIni();
+
+ T instance;
+
+ if (CollectionUtils.isEmpty(ini)) {
+ log.debug("No populated Ini available. Creating a default instance.");
+ instance = createDefaultInstance();
+ if (instance == null) {
+ String msg = getClass().getName() + " implementation did not return a default instance in " +
+ "the event of a null/empty Ini configuration. This is required to support the " +
+ "Factory interface. Please check your implementation.";
+ throw new IllegalStateException(msg);
+ }
+ } else {
+ log.debug("Creating instance from Ini [" + ini + "]");
+ instance = createInstance(ini);
+ if (instance == null) {
+ String msg = getClass().getName() + " implementation did not return a constructed instance from " +
+ "the createInstance(Ini) method implementation.";
+ throw new IllegalStateException(msg);
+ }
+ }
+
+ return instance;
+ }
+
+ protected abstract T createInstance(Ini ini);
+
+ protected abstract T createDefaultInstance();
+}
Propchange: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java?rev=948527&r1=948526&r2=948527&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java Wed May 26 18:34:28 2010
@@ -1,259 +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.shiro.config;
-
-import org.apache.shiro.mgt.DefaultSecurityManager;
-import org.apache.shiro.mgt.RealmSecurityManager;
-import org.apache.shiro.mgt.SecurityManager;
-import org.apache.shiro.realm.Realm;
-import org.apache.shiro.realm.RealmFactory;
-import org.apache.shiro.realm.text.IniRealm;
-import org.apache.shiro.util.CollectionUtils;
-import org.apache.shiro.util.Factory;
-import org.apache.shiro.util.LifecycleUtils;
-import org.apache.shiro.util.Nameable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.*;
-
-/**
- * A {@link Factory} that creates {@link SecurityManager} instances based on {@link Ini} configuration.
- *
- * @author The Apache Shiro Project (shiro-dev@incubator.apache.org)
- * @since 1.0
- */
-public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {
-
- public static final String MAIN_SECTION_NAME = "main";
-
- public static final String SECURITY_MANAGER_NAME = "securityManager";
- public static final String INI_REALM_NAME = "iniRealm";
-
- private static transient final Logger log = LoggerFactory.getLogger(IniSecurityManagerFactory.class);
-
- private ReflectionBuilder builder;
-
- /**
- * Creates a new instance. See the {@link #getInstance()} JavaDoc for detailed explanation of how an INI
- * source will be resolved to use to build the instance.
- */
- public IniSecurityManagerFactory() {
- }
-
- public IniSecurityManagerFactory(Ini config) {
- setIni(config);
- }
-
- public IniSecurityManagerFactory(String iniResourcePath) {
- this(Ini.fromResourcePath(iniResourcePath));
- }
-
- public Map<String, ?> getBeans() {
- return this.builder != null ? Collections.unmodifiableMap(builder.getObjects()) : null;
- }
-
- private SecurityManager getSecurityManagerBean() {
- return builder.getBean(SECURITY_MANAGER_NAME, SecurityManager.class);
- }
-
- protected SecurityManager createDefaultInstance() {
- return new DefaultSecurityManager();
- }
-
- protected SecurityManager createInstance(Ini ini) {
- if (CollectionUtils.isEmpty(ini)) {
- throw new NullPointerException("Ini argument cannot be null or empty.");
- }
- SecurityManager securityManager = createSecurityManager(ini);
- if (securityManager == null) {
- String msg = SecurityManager.class + " instance cannot be null.";
- throw new ConfigurationException(msg);
- }
- return securityManager;
- }
-
- private SecurityManager createSecurityManager(Ini ini) {
- Ini.Section mainSection = ini.getSection(MAIN_SECTION_NAME);
- if (CollectionUtils.isEmpty(mainSection)) {
- //try the default:
- mainSection = ini.getSection(Ini.DEFAULT_SECTION_NAME);
- }
- return createSecurityManager(ini, mainSection);
- }
-
- protected boolean isAutoApplyRealms(SecurityManager securityManager) {
- boolean autoApply = true;
- if (securityManager instanceof RealmSecurityManager) {
- //only apply realms if they haven't been explicitly set by the user:
- RealmSecurityManager realmSecurityManager = (RealmSecurityManager) securityManager;
- Collection<Realm> realms = realmSecurityManager.getRealms();
- if (!CollectionUtils.isEmpty(realms)) {
- log.info("Realms have been explicitly set on the SecurityManager instance - auto-setting of " +
- "realms will not occur.");
- autoApply = false;
- }
- }
- return autoApply;
- }
-
- @SuppressWarnings({"unchecked"})
- private SecurityManager createSecurityManager(Ini ini, Ini.Section mainSection) {
-
- Map<String, ?> defaults = createDefaults(ini, mainSection);
- Map<String, ?> objects = buildInstances(mainSection, defaults);
-
- SecurityManager securityManager = getSecurityManagerBean();
-
- boolean autoApplyRealms = isAutoApplyRealms(securityManager);
-
- if (autoApplyRealms) {
- //realms and realm factory might have been created - pull them out first so we can
- //initialize the securityManager:
- Collection<Realm> realms = getRealms(objects);
- //set them on the SecurityManager
- if (!CollectionUtils.isEmpty(realms)) {
- applyRealmsToSecurityManager(realms, securityManager);
- }
- }
-
- initRealms(securityManager);
-
- return securityManager;
- }
-
- private void initRealms(SecurityManager securityManager) {
- Collection<Realm> realms = getRealms(securityManager);
- if (!CollectionUtils.isEmpty(realms)) {
- LifecycleUtils.init(realms);
- }
- }
-
- private Collection<Realm> getRealms(SecurityManager securityManager) {
- assertRealmSecurityManager(securityManager);
- return ((RealmSecurityManager) securityManager).getRealms();
- }
-
- protected Map<String, ?> createDefaults(Ini ini, Ini.Section mainSection) {
- Map<String, Object> defaults = new LinkedHashMap<String, Object>();
-
- SecurityManager securityManager = createDefaultInstance();
- defaults.put(SECURITY_MANAGER_NAME, securityManager);
-
- if (shouldImplicitlyCreateRealm(ini)) {
- Realm realm = createRealm(ini);
- if (realm != null) {
- defaults.put(INI_REALM_NAME, realm);
- }
- }
-
- return defaults;
- }
-
- private Map<String, ?> buildInstances(Ini.Section section, Map<String, ?> defaults) {
- this.builder = new ReflectionBuilder(defaults);
- return this.builder.buildObjects(section);
- }
-
- private void addToRealms(Collection<Realm> realms, RealmFactory factory) {
- LifecycleUtils.init(factory);
- Collection<Realm> factoryRealms = factory.getRealms();
- if (!CollectionUtils.isEmpty(realms)) {
- realms.addAll(factoryRealms);
- }
- }
-
- private Collection<Realm> getRealms(Map<String, ?> instances) {
-
- //realms and realm factory might have been created - pull them out first so we can
- //initialize the securityManager:
- List<Realm> realms = new ArrayList<Realm>();
-
- //iterate over the map entries to pull out the realm factory(s):
- for (Map.Entry<String, ?> entry : instances.entrySet()) {
-
- String name = entry.getKey();
- Object value = entry.getValue();
-
- if (value instanceof RealmFactory) {
- addToRealms(realms, (RealmFactory) value);
- } else if (value instanceof Realm) {
- Realm realm = (Realm) value;
- //set the name if null:
- String existingName = realm.getName();
- if (existingName == null || existingName.startsWith(realm.getClass().getName())) {
- if (realm instanceof Nameable) {
- ((Nameable) realm).setName(name);
- log.debug("Applied name '{}' to Nameable realm instance {}", name, realm);
- } else {
- log.info("Realm does not implement the {} interface. Configured name will not be applied.",
- Nameable.class.getName());
- }
- }
- realms.add(realm);
- }
- }
-
- return realms;
- }
-
- private void assertRealmSecurityManager(SecurityManager securityManager) {
- if (securityManager == null) {
- throw new NullPointerException("securityManager instance cannot be null");
- }
- if (!(securityManager instanceof RealmSecurityManager)) {
- String msg = "securityManager instance is not a " + RealmSecurityManager.class.getName() +
- " instance. This is required to access or configure realms on the instance.";
- throw new ConfigurationException(msg);
- }
- }
-
- protected void applyRealmsToSecurityManager(Collection<Realm> realms, SecurityManager securityManager) {
- assertRealmSecurityManager(securityManager);
- ((RealmSecurityManager) securityManager).setRealms(realms);
- }
-
- /**
- * Returns {@code true} if the Ini contains account data and a {@code Realm} should be implicitly
- * {@link #createRealm(Ini) created} to reflect the account data, {@code false} if no realm should be implicitly
- * created.
- *
- * @param ini the Ini instance to inspect for account data resulting in an implicitly created realm.
- * @return {@code true} if the Ini contains account data and a {@code Realm} should be implicitly
- * {@link #createRealm(Ini) created} to reflect the account data, {@code false} if no realm should be
- * implicitly created.
- */
- protected boolean shouldImplicitlyCreateRealm(Ini ini) {
- return !CollectionUtils.isEmpty(ini) &&
- (!CollectionUtils.isEmpty(ini.getSection(IniRealm.ROLES_SECTION_NAME)) ||
- !CollectionUtils.isEmpty(ini.getSection(IniRealm.USERS_SECTION_NAME)));
- }
-
- /**
- * Creates a {@code Realm} from the Ini instance containing account data.
- *
- * @param ini the Ini instance from which to acquire the account data.
- * @return a new Realm instance reflecting the account data discovered in the {@code Ini}.
- */
- protected Realm createRealm(Ini ini) {
- IniRealm realm = new IniRealm(ini);
- realm.setName(INI_REALM_NAME);
- return realm;
- }
+/*
+ * 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.shiro.config;
+
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.mgt.RealmSecurityManager;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.RealmFactory;
+import org.apache.shiro.realm.text.IniRealm;
+import org.apache.shiro.util.CollectionUtils;
+import org.apache.shiro.util.Factory;
+import org.apache.shiro.util.LifecycleUtils;
+import org.apache.shiro.util.Nameable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+/**
+ * A {@link Factory} that creates {@link SecurityManager} instances based on {@link Ini} configuration.
+ *
+ * @author The Apache Shiro Project (shiro-dev@incubator.apache.org)
+ * @since 1.0
+ */
+public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {
+
+ public static final String MAIN_SECTION_NAME = "main";
+
+ public static final String SECURITY_MANAGER_NAME = "securityManager";
+ public static final String INI_REALM_NAME = "iniRealm";
+
+ private static transient final Logger log = LoggerFactory.getLogger(IniSecurityManagerFactory.class);
+
+ private ReflectionBuilder builder;
+
+ /**
+ * Creates a new instance. See the {@link #getInstance()} JavaDoc for detailed explanation of how an INI
+ * source will be resolved to use to build the instance.
+ */
+ public IniSecurityManagerFactory() {
+ }
+
+ public IniSecurityManagerFactory(Ini config) {
+ setIni(config);
+ }
+
+ public IniSecurityManagerFactory(String iniResourcePath) {
+ this(Ini.fromResourcePath(iniResourcePath));
+ }
+
+ public Map<String, ?> getBeans() {
+ return this.builder != null ? Collections.unmodifiableMap(builder.getObjects()) : null;
+ }
+
+ private SecurityManager getSecurityManagerBean() {
+ return builder.getBean(SECURITY_MANAGER_NAME, SecurityManager.class);
+ }
+
+ protected SecurityManager createDefaultInstance() {
+ return new DefaultSecurityManager();
+ }
+
+ protected SecurityManager createInstance(Ini ini) {
+ if (CollectionUtils.isEmpty(ini)) {
+ throw new NullPointerException("Ini argument cannot be null or empty.");
+ }
+ SecurityManager securityManager = createSecurityManager(ini);
+ if (securityManager == null) {
+ String msg = SecurityManager.class + " instance cannot be null.";
+ throw new ConfigurationException(msg);
+ }
+ return securityManager;
+ }
+
+ private SecurityManager createSecurityManager(Ini ini) {
+ Ini.Section mainSection = ini.getSection(MAIN_SECTION_NAME);
+ if (CollectionUtils.isEmpty(mainSection)) {
+ //try the default:
+ mainSection = ini.getSection(Ini.DEFAULT_SECTION_NAME);
+ }
+ return createSecurityManager(ini, mainSection);
+ }
+
+ protected boolean isAutoApplyRealms(SecurityManager securityManager) {
+ boolean autoApply = true;
+ if (securityManager instanceof RealmSecurityManager) {
+ //only apply realms if they haven't been explicitly set by the user:
+ RealmSecurityManager realmSecurityManager = (RealmSecurityManager) securityManager;
+ Collection<Realm> realms = realmSecurityManager.getRealms();
+ if (!CollectionUtils.isEmpty(realms)) {
+ log.info("Realms have been explicitly set on the SecurityManager instance - auto-setting of " +
+ "realms will not occur.");
+ autoApply = false;
+ }
+ }
+ return autoApply;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private SecurityManager createSecurityManager(Ini ini, Ini.Section mainSection) {
+
+ Map<String, ?> defaults = createDefaults(ini, mainSection);
+ Map<String, ?> objects = buildInstances(mainSection, defaults);
+
+ SecurityManager securityManager = getSecurityManagerBean();
+
+ boolean autoApplyRealms = isAutoApplyRealms(securityManager);
+
+ if (autoApplyRealms) {
+ //realms and realm factory might have been created - pull them out first so we can
+ //initialize the securityManager:
+ Collection<Realm> realms = getRealms(objects);
+ //set them on the SecurityManager
+ if (!CollectionUtils.isEmpty(realms)) {
+ applyRealmsToSecurityManager(realms, securityManager);
+ }
+ }
+
+ initRealms(securityManager);
+
+ return securityManager;
+ }
+
+ private void initRealms(SecurityManager securityManager) {
+ Collection<Realm> realms = getRealms(securityManager);
+ if (!CollectionUtils.isEmpty(realms)) {
+ LifecycleUtils.init(realms);
+ }
+ }
+
+ private Collection<Realm> getRealms(SecurityManager securityManager) {
+ assertRealmSecurityManager(securityManager);
+ return ((RealmSecurityManager) securityManager).getRealms();
+ }
+
+ protected Map<String, ?> createDefaults(Ini ini, Ini.Section mainSection) {
+ Map<String, Object> defaults = new LinkedHashMap<String, Object>();
+
+ SecurityManager securityManager = createDefaultInstance();
+ defaults.put(SECURITY_MANAGER_NAME, securityManager);
+
+ if (shouldImplicitlyCreateRealm(ini)) {
+ Realm realm = createRealm(ini);
+ if (realm != null) {
+ defaults.put(INI_REALM_NAME, realm);
+ }
+ }
+
+ return defaults;
+ }
+
+ private Map<String, ?> buildInstances(Ini.Section section, Map<String, ?> defaults) {
+ this.builder = new ReflectionBuilder(defaults);
+ return this.builder.buildObjects(section);
+ }
+
+ private void addToRealms(Collection<Realm> realms, RealmFactory factory) {
+ LifecycleUtils.init(factory);
+ Collection<Realm> factoryRealms = factory.getRealms();
+ if (!CollectionUtils.isEmpty(realms)) {
+ realms.addAll(factoryRealms);
+ }
+ }
+
+ private Collection<Realm> getRealms(Map<String, ?> instances) {
+
+ //realms and realm factory might have been created - pull them out first so we can
+ //initialize the securityManager:
+ List<Realm> realms = new ArrayList<Realm>();
+
+ //iterate over the map entries to pull out the realm factory(s):
+ for (Map.Entry<String, ?> entry : instances.entrySet()) {
+
+ String name = entry.getKey();
+ Object value = entry.getValue();
+
+ if (value instanceof RealmFactory) {
+ addToRealms(realms, (RealmFactory) value);
+ } else if (value instanceof Realm) {
+ Realm realm = (Realm) value;
+ //set the name if null:
+ String existingName = realm.getName();
+ if (existingName == null || existingName.startsWith(realm.getClass().getName())) {
+ if (realm instanceof Nameable) {
+ ((Nameable) realm).setName(name);
+ log.debug("Applied name '{}' to Nameable realm instance {}", name, realm);
+ } else {
+ log.info("Realm does not implement the {} interface. Configured name will not be applied.",
+ Nameable.class.getName());
+ }
+ }
+ realms.add(realm);
+ }
+ }
+
+ return realms;
+ }
+
+ private void assertRealmSecurityManager(SecurityManager securityManager) {
+ if (securityManager == null) {
+ throw new NullPointerException("securityManager instance cannot be null");
+ }
+ if (!(securityManager instanceof RealmSecurityManager)) {
+ String msg = "securityManager instance is not a " + RealmSecurityManager.class.getName() +
+ " instance. This is required to access or configure realms on the instance.";
+ throw new ConfigurationException(msg);
+ }
+ }
+
+ protected void applyRealmsToSecurityManager(Collection<Realm> realms, SecurityManager securityManager) {
+ assertRealmSecurityManager(securityManager);
+ ((RealmSecurityManager) securityManager).setRealms(realms);
+ }
+
+ /**
+ * Returns {@code true} if the Ini contains account data and a {@code Realm} should be implicitly
+ * {@link #createRealm(Ini) created} to reflect the account data, {@code false} if no realm should be implicitly
+ * created.
+ *
+ * @param ini the Ini instance to inspect for account data resulting in an implicitly created realm.
+ * @return {@code true} if the Ini contains account data and a {@code Realm} should be implicitly
+ * {@link #createRealm(Ini) created} to reflect the account data, {@code false} if no realm should be
+ * implicitly created.
+ */
+ protected boolean shouldImplicitlyCreateRealm(Ini ini) {
+ return !CollectionUtils.isEmpty(ini) &&
+ (!CollectionUtils.isEmpty(ini.getSection(IniRealm.ROLES_SECTION_NAME)) ||
+ !CollectionUtils.isEmpty(ini.getSection(IniRealm.USERS_SECTION_NAME)));
+ }
+
+ /**
+ * Creates a {@code Realm} from the Ini instance containing account data.
+ *
+ * @param ini the Ini instance from which to acquire the account data.
+ * @return a new Realm instance reflecting the account data discovered in the {@code Ini}.
+ */
+ protected Realm createRealm(Ini ini) {
+ IniRealm realm = new IniRealm(ini);
+ realm.setName(INI_REALM_NAME);
+ return realm;
+ }
}
\ No newline at end of file
Propchange: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
------------------------------------------------------------------------------
svn:eol-style = native