Skip to content
Commits on Source (11)
......@@ -39,4 +39,4 @@ target/
#
release.properties
pom.xml.*
-
-
Contributing to Apache Shiro
=======================================
Summary
-------
This document covers how to contribute to the Apache Shiro project. These instructions assume you have a GitHub.com account, so if you don't have one you will have to create one. Your proposed code changes will be published to your own fork of the Apache Shiro project and you will submit a Pull Request for your changes to be added.
_Lets get started!!!_
Fork the code
-------------
In your browser, navigate to: [https://github.com/apache/shiro](https://github.com/apache/shiro)
Fork the repository by clicking on the 'Fork' button on the top right hand side. The fork will happen and you will be taken to your own fork of the repository. Copy the Git repository URL by clicking on the clipboard next to the URL on the right hand side of the page under '**HTTPS** clone URL'. You will paste this URL when doing the following `git clone` command.
On your computer, follow these steps to setup a local repository for working on Apache Shiro:
``` bash
$ git clone https://github.com/YOUR_ACCOUNT/shiro.git
$ cd shiro
$ git remote add upstream https://github.com/apache/shiro.git
$ git checkout master
$ git fetch upstream
$ git rebase upstream/master
```
Making changes
--------------
It is important that you create a new branch to make changes on and that you do not change the `master` branch (other than to rebase in changes from `upstream/master`). In this example I will assume you will be making your changes to a branch called `feature_x`. This `feature_x` branch will be created on your local repository and will be pushed to your forked repository on GitHub. Once this branch is on your fork you will create a Pull Request for the changes to be added to the Apache Shiro project.
It is best practice to create a new branch each time you want to contribute to the project and only track the changes for that pull request in this branch.
``` bash
$ git checkout -b feature_x
(make your changes)
$ git status
$ git add .
$ git commit -a -m "descriptive commit message for your changes"
```
> The `-b` specifies that you want to create a new branch called `feature_x`. You only specify `-b` the first time you checkout because you are creating a new branch. Once the `feature_x` branch exists, you can later switch to it with only `git checkout feature_x`.
Rebase `feature_x` to include updates from `upstream/master`
------------------------------------------------------------
It is important that you maintain an up-to-date `master` branch in your local repository. This is done by rebasing in the code changes from `upstream/master` (the official Apache Shiro project repository) into your local repository. You will want to do this before you start working on a feature as well as right before you submit your changes as a pull request. I recommend you do this process periodically while you work to make sure you are working off the most recent project code.
This process will do the following:
1. Checkout your local `master` branch
2. Synchronize your local `master` branch with the `upstream/master` so you have all the latest changes from the project
3. Rebase the latest project code into your `feature_x` branch so it is up-to-date with the upstream code
``` bash
$ git checkout master
$ git fetch upstream
$ git rebase upstream/master
$ git checkout feature_x
$ git rebase master
```
> Now your `feature_x` branch is up-to-date with all the code in `upstream/master`.
Make a GitHub Pull Request to contribute your changes
-----------------------------------------------------
When you are happy with your changes and you are ready to contribute them, you will create a Pull Request on GitHub to do so. This is done by pushing your local changes to your forked repository (default remote name is `origin`) and then initiating a pull request on GitHub.
> **IMPORTANT:** Make sure you have rebased your `feature_x` branch to include the latest code from `upstream/master` _before_ you do this.
``` bash
$ git push origin master
$ git push origin feature_x
```
Now that the `feature_x` branch has been pushed to your GitHub repository, you can initiate the pull request.
To initiate the pull request, do the following:
1. In your browser, navigate to your forked repository: [https://github.com/YOUR_ACCOUNT/shiro](https://github.com/YOUR_ACCOUNT/shiro)
2. Click the new button called '**Compare & pull request**' that showed up just above the main area in your forked repository
3. Validate the pull request will be into the upstream `master` and will be from your `feature_x` branch
4. Enter a detailed description of the work you have done and then click '**Send pull request**'
If you are requested to make modifications to your proposed changes, make the changes locally on your `feature_x` branch, re-push the `feature_x` branch to your fork. The existing pull request should automatically pick up the change and update accordingly.
Cleaning up after a successful pull request
-------------------------------------------
Once the `feature_x` branch has been committed into the `upstream/master` branch, your local `feature_x` branch and the `origin/feature_x` branch are no longer needed. If you want to make additional changes, restart the process with a new branch.
> **IMPORTANT:** Make sure that your changes are in `upstream/master` before you delete your `feature_x` and `origin/feature_x` branches!
You can delete these deprecated branches with the following:
``` bash
$ git checkout master
$ git branch -D feature_x
$ git push origin :feature_x
```
[<img src="http://shiro.apache.org/assets/images/apache-shiro-logo.png" align="right" />](http://shiro.apache.org)
[![Build Status](https://builds.apache.org/job/Shiro-master/badge/icon)](https://builds.apache.org/job/Shiro-master)
[![Maven Central](https://img.shields.io/maven-central/v/org.apache.shiro/shiro-core.svg)]()
Apache Shiro
============
[Apache Shiro](http://shiro.apache.org) is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.
Documentation and Examples
--------------------------
http://shiro.apache.org
Tutorials
---------
* [10 Minute Tutorial](http://shiro.apache.org/10-minute-tutorial.html)
* [Web Application](http://shiro.apache.org/webapp-tutorial.html)
License
-------
[Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt)
......@@ -22,17 +22,45 @@
<parent>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-root</artifactId>
<version>1.3.2</version>
<version>1.4.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shiro-all</artifactId>
<name>Apache Shiro :: Jar Bundle</name>
<description>Creates a bundled Shiro .jar from the module jars</description>
<packaging>jar</packaging>
<name>Apache Shiro :: All (aggregate jar)</name>
<description>Creates an aggregate jar that contains the contents of all other Shiro module .jars (aka an 'uber jar')</description>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-lang</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-config-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-config-ogdl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-crypto-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-crypto-hash</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-crypto-cipher</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-event</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
......@@ -41,74 +69,54 @@
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-aspectj</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<artifactId>shiro-guice</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<artifactId>shiro-hazelcast</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-guice</artifactId>
<artifactId>shiro-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3.1</version>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<!-- We _do_ want the assembly output to be the actual artifact produced for this Maven module. -->
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>package</phase>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>shade</goal>
<goal>single</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>${project.groupId}:shiro-core</include>
<include>${project.groupId}:shiro-web</include>
<include>${project.groupId}:shiro-ehcache</include>
<include>${project.groupId}:shiro-quartz</include>
<include>${project.groupId}:shiro-spring</include>
</includes>
</artifactSet>
<!-- <transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer">
<projectName>Apache ActiveMQ</projectName>
</transformer>
</transformers> -->
</configuration>
</execution>
</executions>
</plugin>
<!-- <plugin>
<groupId>org.apache.geronimo.genesis.plugins</groupId>
<artifactId>tools-maven-plugin</artifactId>
<executions>
<execution>
<id>verify-legal-files</id>
<phase>verify</phase>
<goals>
<goal>verify-legal-files</goal>
</goals>
<configuration>
<strict>false</strict>
</configuration>
</execution>
</executions>
</plugin> -->
</plugins>
</build>
<reporting>
......
<!--
~ 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.
-->
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>jar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>true</unpack>
<useTransitiveDependencies>false</useTransitiveDependencies>
</dependencySet>
</dependencySets>
</assembly>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-root</artifactId>
<version>1.4.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shiro-cache</artifactId>
<name>Apache Shiro :: Cache</name>
<packaging>bundle</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>org.apache.shiro.cache</Bundle-SymbolicName>
<Export-Package>org.apache.shiro.cache*;version=${project.version}</Export-Package>
<Import-Package>
org.apache.shiro*;version="${shiro.osgi.importRange}",
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-lang</artifactId>
</dependency>
</dependencies>
</project>
......@@ -18,8 +18,6 @@
*/
package org.apache.shiro.cache;
import org.apache.shiro.util.CollectionUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
......@@ -84,7 +82,7 @@ public class MapCache<K, V> implements Cache<K, V> {
public Collection<V> values() {
Collection<V> values = map.values();
if (!CollectionUtils.isEmpty(values)) {
if (!map.isEmpty()) {
return Collections.unmodifiableCollection(values);
}
return Collections.emptySet();
......
......@@ -17,6 +17,6 @@
* under the License.
*/
/**
* Caching support used to enhance performance for any security operation.
* Caching support used to enhance performance for security operations.
*/
package org.apache.shiro.cache;
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-config</artifactId>
<version>1.4.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shiro-config-core</artifactId>
<name>Apache Shiro :: Configuration :: Core</name>
<packaging>bundle</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>org.apache.shiro.config.core</Bundle-SymbolicName>
<Export-Package>org.apache.shiro.config*;version=${project.version}</Export-Package>
<Import-Package>
org.apache.shiro*;version="${shiro.osgi.importRange}",
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-lang</artifactId>
</dependency>
</dependencies>
</project>
......@@ -19,7 +19,6 @@
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;
......@@ -303,6 +302,57 @@ public class Ini implements Map<String, Ini.Section> {
}
}
/**
* Merges the contents of <code>m</code>'s {@link Section} objects into self.
* This differs from {@link Ini#putAll(Map)}, in that each section is merged with the existing one.
* For example the following two ini blocks are merged and the result is the third<BR/>
* <p>
* Initial:
* <pre>
* <code>[section1]
* key1 = value1
*
* [section2]
* key2 = value2
* </code> </pre>
*
* To be merged:
* <pre>
* <code>[section1]
* foo = bar
*
* [section2]
* key2 = new value
* </code> </pre>
*
* Result:
* <pre>
* <code>[section1]
* key1 = value1
* foo = bar
*
* [section2]
* key2 = new value
* </code> </pre>
*
* </p>
*
* @param m map to be merged
* @since 1.4
*/
public void merge(Map<String, Section> m) {
if (m != null) {
for (Entry<String, Section> entry : m.entrySet()) {
Section section = this.getSection(entry.getKey());
if (section == null) {
section = addSection(entry.getKey());
}
section.putAll(entry.getValue());
}
}
}
private void addSection(String name, StringBuilder content) {
if (content.length() > 0) {
String contentString = content.toString();
......@@ -387,7 +437,7 @@ public class Ini implements Map<String, Ini.Section> {
}
public String toString() {
if (CollectionUtils.isEmpty(this.sections)) {
if (this.sections == null || this.sections.isEmpty()) {
return "<empty INI>";
} else {
StringBuilder sb = new StringBuilder("sections=");
......
......@@ -21,7 +21,8 @@ package org.apache.shiro.config;
import static org.junit.Assert.*;
import org.junit.Test;
import java.util.Scanner;
import static org.hamcrest.Matchers.*;
/**
* Unit test for the {@link Ini} class.
......@@ -35,8 +36,8 @@ public class IniTest {
@Test
public void testNoSections() {
String test =
"prop1 = value1" + NL +
"prop2 = value2";
"prop1 = value1" + NL +
"prop2 = value2";
Ini ini = new Ini();
ini.load(test);
......@@ -160,4 +161,104 @@ public class IniTest {
assertEquals("value 4", section.get("prop4"));
assertEquals("some long value", section.get("prop5"));
}
/**
* @since 1.4
*/
@Test
public void testPutAll() {
Ini ini1 = new Ini();
ini1.setSectionProperty("section1", "key1", "value1");
Ini ini2 = new Ini();
ini2.setSectionProperty("section2", "key2", "value2");
ini1.putAll(ini2);
assertThat(ini1.getSectionNames(), allOf(
hasItem("section1"),
hasItem("section2")
));
// two sections each with one property
assertThat(ini1.getSectionNames(), hasSize(2));
assertThat(ini1.getSection("section2"), aMapWithSize(1));
assertThat(ini1.getSection("section1"), aMapWithSize(1));
// adding a value directly to ini2's section will update ini1
ini2.setSectionProperty("section2", "key2.2", "value2.2");
assertThat(ini1.getSection("section2"), aMapWithSize(2));
Ini ini3 = new Ini();
ini3.setSectionProperty("section1", "key1.3", "value1.3");
// this will replace the whole section
ini1.putAll(ini3);
assertThat(ini1.getSection("section1"), aMapWithSize(1));
}
/**
* @since 1.4
*/
@Test
public void testMerge() {
Ini ini1 = new Ini();
ini1.setSectionProperty("section1", "key1", "value1");
Ini ini2 = new Ini();
ini2.setSectionProperty("section2", "key2", "value2");
ini1.merge(ini2);
assertThat(ini1.getSectionNames(), allOf(
hasItem("section1"),
hasItem("section2")
));
// two sections each with one property
assertThat(ini1.getSectionNames(), hasSize(2));
assertThat(ini1.getSection("section2"), aMapWithSize(1));
assertThat(ini1.getSection("section1"), aMapWithSize(1));
// updating the original ini2, will NOT effect ini1
ini2.setSectionProperty("section2", "key2.2", "value2.2");
assertThat(ini1.getSection("section2"), aMapWithSize(1));
Ini ini3 = new Ini();
ini3.setSectionProperty("section1", "key1.3", "value1.3");
// after merging the section will contain 2 values
ini1.merge(ini3);
assertThat(ini1.getSection("section1"), aMapWithSize(2));
}
/**
* @since 1.4
*/
@Test
public void testCreateWithDefaults() {
Ini ini1 = new Ini();
ini1.setSectionProperty("section1", "key1", "value1");
Ini ini2 = new Ini(ini1);
ini2.setSectionProperty("section2", "key2", "value2");
assertThat(ini2.getSectionNames(), allOf(
hasItem("section1"),
hasItem("section2")
));
// two sections each with one property
assertThat(ini2.getSectionNames(), hasSize(2));
assertThat(ini2.getSection("section2"), aMapWithSize(1));
assertThat(ini2.getSection("section1"), aMapWithSize(1));
// updating the original ini1, will NOT effect ini2
ini1.setSectionProperty("section1", "key1.1", "value1.1");
assertThat(ini2.getSection("section1"), allOf(aMapWithSize(1), hasEntry("key1", "value1")));
}
}