+* separate security into product and test where test depends on JPA 2.0 implementations
+ and test is not deployed to the central maven repo.
+* move codestyle to separate svn project.
+* add cdi subproject
* refactor: Create jpa subproject with separate subprojects for api, hibernate,
toplink-essentials and eclipselink
Each subproject contains the required repo settings
-* Maven profile for nonrelease which is dactivated when release is active.
-* Have toplink, eclipselink, hibernate profiles that are deactivated by
- release and active by default.
-
-* add cdi subproject to the utils
+
+* update mythtv project for java ee 6
* add schemagen for user management part.
+* reimplement photos application using wicket
* JPA 2.0 implementation for security.
+* change tracking for all projects with changes plugin
+
+* complete presentation of all wamblee stuff on wamblee.org.
+* maven sites for each subproject accessible through wamblee.org
+* overview pages for separate areas
+
+* create passwords application
+
--- /dev/null
+package org.wamblee.hibernatejpa;
+
+/**
+ * Dummy class to force generation of javadoc.
+ * This is required for deploy to oss.sonatype.org to work.
+ *
+ * @author Erik Brakkee
+ */
+public class JavadocDummyForSonatype {
+ // Empty
+}
</developer>
</developers>
- <modules>
+ <modules>
<module>support</module>
<module>system</module>
<module>hibernate-jpa</module>
<scope>compile</scope>
</dependency>
-
-
</dependencies>
</dependencyManagement>
<goals>javadoc:jar deploy</goals>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.5</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-code-style</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4</version>
<fileFormat>UNIX</fileFormat>
<convention>org.wamblee.jalopy.xml</convention>
</configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-code-style</artifactId>
+ <version>1.1-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
+ <version>2.3</version>
<executions>
<execution>
<goals>
</reportSet>
</reportSets>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>2.3.1</version>
+ <configuration>
+ <xmlOutput>true</xmlOutput>
+ <!-- Optional derectory to put findbugs xdoc xml report -->
+ <xmlOutputDirectory>target/site</xmlOutputDirectory>
+ <findbugsXmlOutput>true</findbugsXmlOutput>
+ <!-- Optional directory to put findbugs xml report -->
+ <findbugsXmlOutputDirectory>target/site</findbugsXmlOutputDirectory>
+ </configuration>
+
+ </plugin>
+
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>changes-maven-plugin</artifactId>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
+ <version>2.3</version>
<configuration>
<formats>
<format>xml</format>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.5</version>
<configuration>
- <configLocation>config/sun_checks.xml</configLocation>
+ <configLocation>org.wamblee.checkstyle.xml</configLocation>
</configuration>
</plugin>
<url>http://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
-
+
</profile>
<profile>
<id>all</id>
--- /dev/null
+
+Security is separated into impl and jpatest because current JPA 2.0 implementations
+(hibernate, eclipse-link) are not available on central maven repo. Therefore, the
+tests that depend on them must be put into a separate jpatest project.
+
--- /dev/null
+<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.wamblee</groupId>
+ <artifactId>wamblee-utils</artifactId>
+ <version>0.2.2</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-security-impl</artifactId>
+ <packaging>jar</packaging>
+ <name>/security/impl</name>
+ <url>http://wamblee.org</url>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-system-general</artifactId>
+ <version>0.2.2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+
+ </dependencies>
+
+</project>
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package org.wamblee.persistence;
+package org.wamblee.security;
import java.io.Serializable;
+import org.wamblee.persistence.Persistent;
+
/**
- * Default implementation of Persistent.
- *
+ * Default implementation of Persistent.
+ *
* @author Erik Brakkee
*/
public abstract class AbstractPersistent implements Persistent {
-
- /**
- * Primary key.
- */
- private Serializable _primaryKey;
-
- /**
- * Version.
- */
- private int _version;
-
- /**
- * Constructs the object.
- *
- */
- protected AbstractPersistent() {
- _primaryKey = null;
- _version = -1;
+
+ private Serializable primaryKey;
+
+ private Number version;
+
+ protected AbstractPersistent() {
+ primaryKey = null;
+ version = -1;
}
-
+
/**
- * Copy constructor.
- * @param aPersistent Object to copy.
+ * Copy constructor.
+ *
+ * @param aPersistent
+ * Object to copy.
*/
protected AbstractPersistent(AbstractPersistent aPersistent) {
- _primaryKey = aPersistent._primaryKey;
- _version = aPersistent._version;
+ primaryKey = aPersistent.primaryKey;
+ version = aPersistent.version;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.persistence.Persistent#getPrimaryKey()
*/
+ @Override
public Serializable getPrimaryKey() {
- return _primaryKey;
+ return primaryKey;
}
-
- /* (non-Javadoc)
- * @see org.wamblee.persistence.Persistent#setPrimaryKey(java.io.Serializable)
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.persistence.Persistent#setPrimaryKey(java.io.Serializable)
*/
+ @Override
public void setPrimaryKey(Serializable aKey) {
- _primaryKey = aKey;
+ primaryKey = aKey;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.persistence.Persistent#getPersistedVersion()
*/
- public int getPersistedVersion() {
- return _version;
+ public Number getPersistedVersion() {
+ return version;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.persistence.Persistent#setPersistedVersion(int)
*/
- public void setPersistedVersion(int aVersion) {
- _version = aVersion;
+ public void setPersistedVersion(Number aVersion) {
+ version = aVersion;
}
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.wamblee.usermgt.User;
+
+/**
+ * Represents an authorization rule to determine whether an operation is allowed
+ * on a resource.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@Table(name = "SEC_AUTH_RULE")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYPE")
+public abstract class AbstractAuthorizationRule implements AuthorizationRule {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ public AbstractAuthorizationRule() {
+ // Empty
+ }
+
+ public AbstractAuthorizationRule(AbstractAuthorizationRule aRule) {
+ primaryKey = aRule.primaryKey;
+ version = aRule.version;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.wamblee.usermgt.UserAccessor;
+
+/**
+ * Service to determine if access to a certain resource is allowed.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@Table(name = "SEC_AUTH_SVC")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYPE")
+@NamedQueries(
+ @NamedQuery(name = AbstractAuthorizationService.QUERY_FIND_BY_NAME,
+ query = "select s from AbstractAuthorizationService s where s.name = :" +
+ AbstractAuthorizationService.NAME_PARAM)
+ )
+public abstract class AbstractAuthorizationService implements AuthorizationService {
+
+ public static final String QUERY_FIND_BY_NAME = "AuthorizationService.findByName";
+ public static final String NAME_PARAM = "name";
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ public AbstractAuthorizationService() {
+ // Empty.
+ }
+
+ public AbstractAuthorizationService(AbstractAuthorizationService aSvc) {
+ primaryKey = aSvc.primaryKey;
+ version = aSvc.version;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+/**
+ * Checks if an operation matches a condition.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@Table(name = "SEC_OPERATION_CONDITION")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYPE")
+public abstract class AbstractOperationCondition implements OperationCondition {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ public AbstractOperationCondition() {
+ // Empty
+ }
+
+ public AbstractOperationCondition(AbstractOperationCondition aCondition) {
+ primaryKey = aCondition.primaryKey;
+ version = aCondition.version;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+/**
+ * Checks if a path satisfies a condition.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@Table(name = "SEC_PATH_CONDITION")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYPE")
+public abstract class AbstractPathCondition implements PathCondition {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ public AbstractPathCondition() {
+ // Empty
+ }
+
+ public AbstractPathCondition(AbstractPathCondition aCondition) {
+ primaryKey = aCondition.primaryKey;
+ version = aCondition.version;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.wamblee.usermgt.User;
+
+/**
+ * Condition used to match a user against a specified set of users.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@Table(name = "SEC_USER_CONDITION")
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "TYPE")
+public abstract class AbstractUserCondition implements UserCondition {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ public AbstractUserCondition() {
+ // Empty.
+ }
+
+ public AbstractUserCondition(AbstractUserCondition aCondition) {
+ primaryKey = aCondition.primaryKey;
+ version = aCondition.version;
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * An superclass of all other operations.
+ * An superclass of all other operations.
*/
public class AllOperation implements Operation {
-
private static final String OPERATION = "all";
-
+
/**
- * Operation name.
+ * Operation name.
*/
- private String _name;
-
+ private String name;
+
/**
- * Constructs an all operation.
- *
+ * Constructs an all operation.
+ *
*/
- public AllOperation() {
- _name = OPERATION;
+ public AllOperation() {
+ name = OPERATION;
}
-
+
/**
* Constructs the operation, this constructor is the one that must be used
- * by subclasses.
- * @param aName Name of the operation. This name must be unique among all operations.
+ * by subclasses.
+ *
+ * @param aName
+ * Name of the operation. This name must be unique among all
+ * operations.
*/
- protected AllOperation(String aName) {
- _name = aName;
+ protected AllOperation(String aName) {
+ name = aName;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.security.authorization.Operation#getName()
*/
public String getName() {
- return _name;
+ return name;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
-import org.wamblee.persistence.AbstractPersistent;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
import org.wamblee.usermgt.User;
/**
- * Matches any user.
- *
+ * Matches any user.
+ *
* @author Erik Brakkee
*/
-public class AnyUserCondition extends AbstractPersistent implements UserCondition {
-
+@Entity
+@DiscriminatorValue("ANYUSER")
+public class AnyUserCondition extends AbstractUserCondition {
/**
- * Constructs the condition.
- *
+ * Constructs the condition.
+ *
*/
- public AnyUserCondition() {
- // Empty.
+ public AnyUserCondition() {
+ // Empty.
}
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.UserCondition#matches(org.wamblee.usermgt.User)
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.UserCondition#matches(org.wamblee.
+ * usermgt.User)
*/
public boolean matches(User aUser) {
- return true;
+ return true;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
- return "AnyUserCondition()";
+ return "AnyUserCondition()";
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * Authorization exception to be thrown when
- * a resouce may not be accessed.
- *
+ * Authorization exception to be thrown when a resouce may not be accessed.
+ *
* @author Erik Brakkee
*/
public class AuthorizationException extends RuntimeException {
-
- private Object _resource;
- private Operation _operation;
+ private Object resource;
+
+ private Operation operation;
+ /**
+ * Creates a new AuthorizationException object.
+ *
+ */
public AuthorizationException(Object aResource, Operation aOperation) {
- super("Operation '" + aOperation + "' not allowed on '" + aResource + "'");
- _resource = aResource;
- _operation = aOperation;
+ super("Operation '" + aOperation + "' not allowed on '" + aResource +
+ "'");
+ resource = aResource;
+ operation = aOperation;
}
-
- public Object getResource() {
- return _resource;
+
+ public Object getResource() {
+ return resource;
}
-
- public Operation getOperation() {
- return _operation;
+
+ public Operation getOperation() {
+ return operation;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
import org.apache.log4j.Logger;
-
/**
- * Inititializer class for authorization rules. This class initializes the
- * authorization rules in case none are present.
+ * Inititializer class for authorization rules. This class initializes the
+ * authorization rules in case none are present.
*/
public class AuthorizationInitializer {
-
- private static final Logger LOGGER = Logger.getLogger(AuthorizationInitializer.class);
+ private static final Logger LOGGER = Logger
+ .getLogger(AuthorizationInitializer.class);
/**
- * Initializes authorization rules in case none are present.
- * @param aService Authorization service.
- * @param aRules Default rules for initialization.
+ * Initializes authorization rules in case none are present.
+ *
+ * @param aService
+ * Authorization service.
+ * @param aRules
+ * Default rules for initialization.
*/
- public AuthorizationInitializer(AuthorizationService aService, AuthorizationRule[] aRules) {
- if ( aService.getRules().length == 0 ) {
- for (AuthorizationRule rule: aRules) {
- LOGGER.info("Appending authorization rule " + rule);
- aService.appendRule(rule);
- }
- }
+ public AuthorizationInitializer(AuthorizationService aService,
+ AbstractAuthorizationRule[] aRules) {
+ if (aService.getRules().length == 0) {
+ for (AbstractAuthorizationRule rule : aRules) {
+ LOGGER.info("Appending authorization rule " + rule);
+ aService.appendRule(rule);
+ }
+ }
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.security.authorization;
/**
* Represents the result of an authorization decision.
- *
+ *
* @author Erik Brakkee
*/
public enum AuthorizationResult {
* Access is granted.
*/
GRANTED,
-
/**
* Access is denied.
*/
DENIED,
-
/**
* Access is undecided.
*/
UNDECIDED,
-
/**
* Unsupported resource.
*/
- UNSUPPORTED_RESOURCE
+ UNSUPPORTED_RESOURCE;
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.security.authorization;
-import org.wamblee.persistence.Persistent;
import org.wamblee.usermgt.User;
/**
- * Represents an authorization rule to determine whether an operation is allowed on a resource.
- *
+ * Represents an authorization rule to determine whether an operation is allowed
+ * on a resource.
+ *
* @author Erik Brakkee
*/
-public interface AuthorizationRule extends Persistent {
-
+public interface AuthorizationRule {
+
/**
- * Returns the supported object types for which this authorization rule applies.
- * This can be used by the authorization service for optimization.
- * @return Array of supported types.
+ * Returns the supported object types for which this authorization rule
+ * applies. This can be used by the authorization service for optimization.
+ *
+ * @return Array of supported types.
*/
- Class[] getSupportedTypes();
+ public abstract Class[] getSupportedTypes();
/**
- * Determines whether an operation is allowed on a certain resource.
- * The rule implementation must be prepared to deal with resources for which it does
- * not apply. In those cases it should return {@link AuthorizationResult#UNSUPPORTED_RESOURCE}.
- * @param aResource Resource.
- * @param anOperation Operation.
- * @param aUser Current user.
- * @return Authorization result.
+ * Determines whether an operation is allowed on a certain resource. The
+ * rule implementation must be prepared to deal with resources for which it
+ * does not apply. In those cases it should return
+ * {@link AuthorizationResult#UNSUPPORTED_RESOURCE}.
+ *
+ * @param aResource
+ * Resource.
+ * @param aOperation
+ * Operation.
+ * @param aUser
+ * Current user.
+ *
+ * @return Authorization result.
*/
- AuthorizationResult isAllowed(Object aResource, Operation anOperation, User aUser);
-}
+ public abstract AuthorizationResult isAllowed(Object aResource,
+ Operation aOperation, User aUser);
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import org.wamblee.usermgt.UserAccessor;
+
+/**
+ * Service to determine if access to a certain resource is allowed.
+ *
+ * @author Erik Brakkee
+ */
+public interface AuthorizationService {
+
+ /**
+ * Checks whether an operation is allowed on a resource.
+ *
+ * @param aResource
+ * Resource.
+ * @param aOperation
+ * Operation.
+ *
+ * @return Checks whether the operation is allowed on a resource.
+ */
+ boolean isAllowed(Object aResource, Operation aOperation);
+
+ /**
+ * Checks if the given operation is allowed on the resource.
+ *
+ * @param <T>
+ * Type of resource
+ * @param aResource
+ * Resource.
+ * @param aOperation
+ * Operation.
+ * @return Resource passed in in case access is allowed
+ * @throws AuthorizationException
+ * In case access is denied.
+ */
+ <T> T check(T aResource, Operation aOperation);
+
+ /**
+ * Gets the authorization rules.
+ *
+ * @return Rules.
+ */
+ AuthorizationRule[] getRules();
+
+ /**
+ * Appends a new authorization rule to the end.
+ *
+ * @param aRule
+ * Rule to append.
+ */
+ void appendRule(AuthorizationRule aRule);
+
+ /**
+ * Removes a rule.
+ *
+ * @param aIndex
+ * Index of the rule to remove.
+ */
+ void removeRule(int aIndex);
+
+ /**
+ * Inserts a rule.
+ *
+ * @param aIndex
+ * Index of the position of the rule after insertion.
+ * @param aRule
+ * Rule to insert.
+ */
+ void insertRuleAfter(int aIndex, AuthorizationRule aRule);
+
+ /**
+ * Sets the user accessor so that the authorization service can get access
+ * to the logged in user.
+ *
+ * @param aUserAccessor
+ * User accessor.
+ */
+ void setUserAccessor(UserAccessor aUserAccessor);
+
+}
\ No newline at end of file
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * Represents an operation to create something.
- *
+ * Represents an operation to create something.
+ *
* @author Erik Brakkee
*/
public class CreateOperation extends AllOperation {
-
private static final String OPERATION = "create";
-
+
/**
- * Constructs the operation.
- *
+ * Constructs the operation.
+ *
*/
- public CreateOperation() {
+ public CreateOperation() {
super(OPERATION);
}
-
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderColumn;
+import javax.persistence.Transient;
+
+import org.wamblee.usermgt.User;
+import org.wamblee.usermgt.UserAccessor;
+
+/**
+ * Default implementation of an authorization service. To determine whether
+ * access to a resource is allowed, the service consults a number of
+ * authorization rules in a fixed order. The first rule that gives a result
+ * GRANTED or DENIED determines the result of the evaluation. Rules that return
+ * any other result are ignoed. If none of the rules match, than access is
+ * denied.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@DiscriminatorValue("DEFAULT")
+public class DefaultAuthorizationService extends AbstractAuthorizationService {
+
+
+ /**
+ * List of ordered authorization rules.
+ */
+ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = AbstractAuthorizationRule.class)
+ @OrderColumn(name = "RULE_INDEX")
+ private List<AuthorizationRule> rules;
+
+ /**
+ * User accessor used to obtain the current user.
+ */
+ @Transient
+ private UserAccessor userAccessor;
+
+ /**
+ * Name for this instance of the authorization service.
+ */
+ private String name;
+
+ /**
+ * Constructs the service.
+ *
+ * @param aAccessor
+ * User accessor.
+ * @param aName
+ * Name of this instance of the service.
+ */
+ public DefaultAuthorizationService(UserAccessor aAccessor, String aName) {
+ rules = new ArrayList<AuthorizationRule>();
+ userAccessor = aAccessor;
+ name = aName;
+ }
+
+ /**
+ * Constructs the authorization service.
+ */
+ public DefaultAuthorizationService() {
+ rules = new ArrayList<AuthorizationRule>();
+ userAccessor = null;
+ name = null;
+ }
+
+ /**
+ * Sets the user accessor.
+ *
+ * @param aUserAccessor
+ * User accessor.
+ */
+ @Override
+ public void setUserAccessor(UserAccessor aUserAccessor) {
+ userAccessor = aUserAccessor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#isAllowed(java
+ * .lang.Object, org.wamblee.security.authorization.Operation)
+ */
+ public boolean isAllowed(Object aResource, Operation aOperation) {
+ User user = userAccessor.getCurrentUser();
+
+ for (AuthorizationRule rule : rules) {
+ switch (rule.isAllowed(aResource, aOperation, user)) {
+ case DENIED:
+ return false;
+
+ case GRANTED:
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.security.authorization.AuthorizationService#check(T,
+ * org.wamblee.security.authorization.Operation)
+ */
+ public <T> T check(T aResource, Operation aOperation) {
+ if (!isAllowed(aResource, aOperation)) {
+ throw new AuthorizationException(aResource, aOperation);
+ }
+
+ return aResource;
+ }
+
+ protected String getName() {
+ return name;
+ }
+
+ public void setName(String aName) {
+ name = aName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.security.authorization.AuthorizationService#getRules()
+ */
+ public AuthorizationRule[] getRules() {
+ return rules.toArray(new AbstractAuthorizationRule[0]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#appendRule(org
+ * .wamblee.security.authorization.AuthorizationRule)
+ */
+ public void appendRule(AuthorizationRule aRule) {
+ rules.add(aRule);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#insertRuleAfter
+ * (int, org.wamblee.security.authorization.AuthorizationRule)
+ */
+ public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
+ rules.add(aIndex, aRule);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#removeRule(int)
+ */
+ public void removeRule(int aIndex) {
+ rules.remove(aIndex);
+ }
+
+ /**
+ * For OR mapping.
+ *
+ * @return The rules.
+ */
+ protected List<AuthorizationRule> getMappedRules() {
+ return rules;
+ }
+
+ /**
+ * For OR mapping.
+ *
+ * @param aRules
+ * The rules.
+ */
+ protected void setMappedRules(List<AuthorizationRule> aRules) {
+ rules = aRules;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Operation registry implementation. This implementation ignores the
+ * distinction between different types of resources and simply assumes that
+ * every operation is applicable to every type of resource.
+ *
+ * @author Erik Brakkee
+ */
+public class DefaultOperationRegistry implements OperationRegistry {
+ private Map<String, Operation> operations;
+
+ /**
+ * Creates a new DefaultOperationRegistry object.
+ *
+ */
+ public DefaultOperationRegistry(Operation[] aOperations) {
+ operations = new TreeMap<String, Operation>();
+
+ for (Operation operation : aOperations) {
+ operations.put(operation.getName(), operation);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.OperationRegistry#getOperations(java
+ * .lang.Class)
+ */
+ public Operation[] getOperations(Class aResourceClass) {
+ return operations.values().toArray(new Operation[0]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.OperationRegistry#encode(org.wamblee
+ * .security.authorization.Operation[])
+ */
+ public String encode(Operation[] aOperations) {
+ StringBuffer buffer = new StringBuffer();
+
+ for (Operation operation : aOperations) {
+ if (buffer.length() > 0) {
+ buffer.append(',');
+ }
+
+ buffer.append(operation.getName());
+ }
+
+ return buffer.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.OperationRegistry#decode(java.lang
+ * .Class, java.lang.String)
+ */
+ public Operation[] decode(Class aResourceClass, String aOperationsString) {
+ return decode(aOperationsString);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.OperationRegistry#decode(java.lang
+ * .String)
+ */
+ public Operation[] decode(String aOperationsString) {
+ if (aOperationsString.length() == 0) {
+ return new Operation[0];
+ }
+
+ String[] names = aOperationsString.split(",");
+ ArrayList<Operation> result = new ArrayList<Operation>();
+
+ for (String name : names) {
+ Operation operation = operations.get(name);
+
+ if (operation == null) {
+ throw new IllegalArgumentException("Unknown operation '" +
+ name + "'");
+ }
+
+ result.add(operation);
+ }
+
+ return result.toArray(new Operation[0]);
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * Deletes the operation.
- *
+ * Deletes the operation.
+ *
* @author Erik Brakkee
*/
public class DeleteOperation extends AllOperation {
-
private static final String OPERATION = "delete";
-
+
/**
- * Constructs the operation.
- *
+ * Constructs the operation.
+ *
*/
- public DeleteOperation() {
+ public DeleteOperation() {
super(OPERATION);
}
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.wamblee.usermgt.User;
+
+
+/**
+ * Checks if a user against a specific group.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@DiscriminatorValue("GROUP")
+public class GroupUserCondition extends AbstractUserCondition {
+ /**
+ * Group the user must be in.
+ */
+ @Column(name = "GRP")
+ private String group;
+
+ /**
+ * Constructs the condition.
+ *
+ * @param aGroup
+ * Group the user must be in.
+ */
+ public GroupUserCondition(String aGroup) {
+ group = aGroup;
+ }
+
+ /**
+ * For OR mapping.
+ *
+ */
+ protected GroupUserCondition() {
+ group = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.UserCondition#matches(org.wamblee.
+ * usermgt.UserAccessor)
+ */
+ public boolean matches(User aUser) {
+ return aUser.isInGroup(group);
+ }
+
+ /**
+ *
+ * @return Returns the group.
+ */
+ protected String getGroup() {
+ return group;
+ }
+
+ /**
+ *
+ * @param aGroup
+ * The group to set.
+ */
+ protected void setGroup(String aGroup) {
+ group = aGroup;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "GroupUserCondition(group=" + group + ")";
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.security.authorization;
-import org.wamblee.persistence.AbstractPersistent;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
/**
* Determiens if an operation is a subclass of a specified operation.
*/
-public class IsaOperationCondition extends AbstractPersistent implements
- OperationCondition {
-
+@Entity
+@DiscriminatorValue("ISA")
+@Access(AccessType.PROPERTY)
+public class IsaOperationCondition extends AbstractOperationCondition {
/**
* Operation that the other operation must be a subclass of.
*/
- private Class<? extends Operation> _operation;
+ private Class<? extends Operation> operation;
/**
* Constructs the condition.
* Operation that an operation must be an instance of.
*/
public IsaOperationCondition(Class<? extends Operation> aOperation) {
- _operation = aOperation;
+ operation = aOperation;
}
/**
*
*/
public IsaOperationCondition() {
- _operation = null;
+ operation = null;
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.security.authorization.OperationCondition#matches(org.wamblee.security.authorization.Operation)
+ * @see
+ * org.wamblee.security.authorization.OperationCondition#matches(org.wamblee
+ * .security.authorization.Operation)
*/
public boolean matches(Operation aOperation) {
- return _operation.isInstance(aOperation);
+ return operation.isInstance(aOperation);
}
/**
*
* @return Operation string.
*/
+ @Column(name = "CLASSNAME")
protected String getOperationString() {
- if (_operation == null) {
- return null;
+ if (operation == null) {
+ return null;
}
- return _operation.getName();
+
+ return operation.getName();
}
/**
*
* @param aOperation
* Operation string.
+ *
*/
protected void setOperationString(String aOperation) {
- if (aOperation == null ) {
+ if (aOperation == null) {
return;
}
- try {
- _operation = (Class<? extends Operation>)Class.forName(aOperation);
- } catch (Exception e) {
- throw new IllegalArgumentException("Unknown class '" + aOperation + "'");
+
+ try {
+ operation = (Class<? extends Operation>) Class.forName(aOperation);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unknown class '" + aOperation +
+ "'");
}
}
*/
@Override
public String toString() {
- return "IsaOperationCondition(operation=" + _operation.getName() + ")";
+ return "IsaOperationCondition(operation=" + operation.getName() + ")";
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * Represents an operation on a resource.
- * An operation should contain no state to be persisted since only the name of the
- * operation is persisted.
- *
+ * Represents an operation on a resource. An operation should contain no state
+ * to be persisted since only the name of the operation is persisted.
+ *
* @author Erik Brakkee
*/
public interface Operation {
-
/**
- * Gets the name of the operation.
- * @return Operation.
+ * Gets the name of the operation.
+ *
+ * @return Operation.
*/
- String getName();
+ String getName();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
-import org.wamblee.persistence.Persistent;
-
/**
- * Checks if an operation matches a condition.
- *
+ * Checks if an operation matches a condition.
+ *
* @author Erik Brakkee
*/
-public interface OperationCondition extends Persistent {
+public interface OperationCondition {
-
/**
- * Determines if the operation matches.
- * @param aOperation Operation.
- * @return True iff the operation matches.
+ * Determines if the operation matches.
+ *
+ * @param aOperation
+ * Operation.
+ *
+ * @return True iff the operation matches.
*/
- boolean matches(Operation aOperation);
-}
+ public abstract boolean matches(Operation aOperation);
+
+}
\ No newline at end of file
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
-
/**
- * Utility to map between a list of operations and a string based
- * on the names of the operations.
- *
+ * Utility to map between a list of operations and a string based on the names
+ * of the operations.
+ *
* @author Erik Brakkee
*/
public interface OperationRegistry {
-
/**
- * Gets the supported operations for a given resource class.
- * @param aResourceClass Resource class.
- * @return Supported operations for that class.
+ * Gets the supported operations for a given resource class.
+ *
+ * @param aResourceClass
+ * Resource class.
+ *
+ * @return Supported operations for that class.
*/
Operation[] getOperations(Class aResourceClass);
-
+
/**
- * Converts a number of operations to a string.
- * @param aOperations Operations to convert.
- * @return String representation of the allowed operations.
+ * Converts a number of operations to a string.
+ *
+ * @param aOperations
+ * Operations to convert.
+ *
+ * @return String representation of the allowed operations.
*/
String encode(Operation[] aOperations);
-
+
/**
* Converts an operations string to an array of operations.
- * @param aResourceClass Resource class.
- * @param aOperationsString Operations string as returned by {@link #encode(Operation[])}.
- * @return Operations array.
+ *
+ * @param aResourceClass
+ * Resource class.
+ * @param aOperationsString
+ * Operations string as returned by {@link #encode(Operation[])}.
+ *
+ * @return Operations array.
*/
Operation[] decode(Class aResourceClass, String aOperationsString);
-
+
/**
* Converts an operations string to an array of operations.
- * @param aOperationsString Operations string as returned by {@link #encode(Operation[])}.
- * @return Operations array.
+ *
+ * @param aOperationsString
+ * Operations string as returned by {@link #encode(Operation[])}.
+ *
+ * @return Operations array.
*/
Operation[] decode(String aOperationsString);
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
-import org.wamblee.persistence.Persistent;
-
/**
- * Checks if a path satisfies a condition.
- *
+ * Checks if a path satisfies a condition.
+ *
* @author Erik Brakkee
*/
-public interface PathCondition extends Persistent {
+public interface PathCondition {
/**
- * Checks if the path matches the condition.
- * @param aPath Path to match.
- * @return True iff the path matches.
+ * Checks if the path matches the condition.
+ *
+ * @param aPath
+ * Path to match.
+ *
+ * @return True iff the path matches.
*/
- boolean matches(String aPath);
-}
+ public abstract boolean matches(String aPath);
+
+}
\ No newline at end of file
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * Represents a read operation on a resource.
- *
+ * Represents a read operation on a resource.
+ *
* @author Erik Brakkee
*/
public class ReadOperation extends AllOperation {
-
private static final String OPERATION = "read";
-
+
/**
- * Constructs the operation.
- *
+ * Constructs the operation.
+ *
*/
- public ReadOperation() {
- super(OPERATION);
+ public ReadOperation() {
+ super(OPERATION);
}
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+/**
+ * Condition to check whether a path matches a given regula expression.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@DiscriminatorValue("REGEXP")
+public class RegexpPathCondition extends AbstractPathCondition {
+ /**
+ * String the path must start with.
+ */
+ private String pattern;
+
+ /**
+ * Constructs the condition.
+ *
+ * @param aPattern
+ * String the path must start with.
+ */
+ public RegexpPathCondition(String aPattern) {
+ pattern = aPattern;
+ }
+
+ /**
+ * For OR mapping.
+ *
+ */
+ protected RegexpPathCondition() {
+ pattern = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.PathCondition#matches(java.lang.String
+ * )
+ */
+ public boolean matches(String aPath) {
+ return aPath.matches(pattern);
+ }
+
+ /**
+ *
+ * @return Returns the _path.
+ */
+ protected String getPattern() {
+ return pattern;
+ }
+
+ /**
+ *
+ * @param aPattern
+ * The _path to set.
+ */
+ protected void setPattern(String aPattern) {
+ pattern = aPattern;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "RegexpCondition(pattern = '" + pattern + "')";
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
/**
- * Condition to check whether a path starts with a given string.
- *
+ * Condition to check whether a path starts with a given string.
+ *
* @author Erik Brakkee
*/
+@Entity
+@DiscriminatorValue("STARTSWITH")
public class StartsWithPathCondition extends RegexpPathCondition {
-
/**
- * Constructs the condition.
- * @param aPath String the path must start with.
+ * Constructs the condition.
+ *
+ * @param aPath
+ * String the path must start with.
*/
- public StartsWithPathCondition(String aPath) {
- super( aPath + ".*");
+ public StartsWithPathCondition(String aPath) {
+ super(aPath + ".*");
}
-
+
/**
- * For OR mapping.
- *
+ * For OR mapping.
+ *
*/
- protected StartsWithPathCondition() {
- super();
+ protected StartsWithPathCondition() {
+ super();
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#toString()
*/
@Override
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import static org.wamblee.security.authorization.AuthorizationResult.*;
+
+import javax.enterprise.inject.Typed;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Transient;
+
+import org.apache.log4j.Logger;
+import org.wamblee.usermgt.User;
+
+/**
+ * Utility base class for implementation of authentication rules based on the
+ * <ul>
+ * <li>The path of the resource. To obtain the path of a resource, subclasses
+ * must implement {@link #getResourcePath(Object)}. Whether a path is
+ * appropriate is determined by a
+ * {@link org.wamblee.security.authorization.AbstractPathCondition}.</li>
+ * <li>The user identity with which the resource is accessed. Whether a user is
+ * appropriate is determined by a
+ * {@link org.wamblee.security.authorization.AbstractUserCondition}.</li>
+ * <li>The operation that is requested. Whether the operation is appropriate is
+ * determined by a {@link org.wamblee.security.authorization.AbstractOperationCondition}
+ * .</li>
+ * </ul>
+ * In case all three conditions match, the condition returns the configured
+ * result passed at construction (GRANTED or DENIED). If the resource is not of
+ * the specified type, the result is UNSUPPORTED_RESOURCE, otherwise, the result
+ * is UNDECIDED.
+ */
+@Entity
+@Access(AccessType.PROPERTY)
+public abstract class UrlAuthorizationRule extends AbstractAuthorizationRule {
+ private static final Logger LOGGER = Logger
+ .getLogger(UrlAuthorizationRule.class);
+
+ /**
+ * Result that the rule will return in case there is a match.
+ */
+ private AuthorizationResult result;
+
+ /**
+ * A condition which specifies which users the rule is for.
+ */
+ private UserCondition userCondition;
+
+ /**
+ * Path the rule applies for.
+ */
+ private PathCondition pathCondition;
+
+ /**
+ * Resource class that the rule applies for.
+ */
+ private Class resourceClass;
+
+ /**
+ * Operation that this rule is for.
+ */
+
+ private OperationCondition operationCondition;
+
+ /**
+ * Constructs an authorization rule. IF the group and path match, then the
+ * provided result will be returned.
+ *
+ * @param aResult
+ * Result of the authorization when the path and group match.
+ * @param aUserCondition
+ * Condition to match users.
+ * @param aPathCondition
+ * Condition to match paths with.
+ * @param aResourceClass
+ * Supported resource class this is for.
+ * @param aOperationCondition
+ * Condition to match the operation with.
+ */
+ protected UrlAuthorizationRule(AuthorizationResult aResult,
+ UserCondition aUserCondition, PathCondition aPathCondition,
+ Class aResourceClass, OperationCondition aOperationCondition) {
+ if (!aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
+ throw new IllegalArgumentException(
+ "Only GRANTED or DENIED may be used: " + aResult);
+ }
+
+ result = aResult;
+ userCondition = aUserCondition;
+ pathCondition = aPathCondition;
+ resourceClass = aResourceClass;
+ operationCondition = aOperationCondition;
+ }
+
+ /**
+ * For OR mapping.
+ *
+ */
+ protected UrlAuthorizationRule(Class aResourceClass) {
+ result = null;
+ userCondition = null;
+ pathCondition = null;
+ resourceClass = aResourceClass;
+ operationCondition = null;
+ }
+
+ /**
+ * For OR mapping.
+ *
+ */
+ protected UrlAuthorizationRule() {
+ result = null;
+ userCondition = null;
+ pathCondition = null;
+ resourceClass = null;
+ operationCondition = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
+ */
+ @Transient
+ public Class[] getSupportedTypes() {
+ return new Class[] { resourceClass };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang
+ * .Object, org.wamblee.security.authorization.Operation)
+ */
+ public AuthorizationResult isAllowed(Object aResource,
+ Operation aOperation, User aUser) {
+ if (!resourceClass.isInstance(aResource)) {
+ return UNSUPPORTED_RESOURCE;
+ }
+
+ String path = getResourcePath(aResource);
+
+ return isAllowed(path, aOperation, aUser);
+ }
+
+ /**
+ * Determines if the operation is allowed on the resource.
+ *
+ * @param aPath
+ * Path of the resource.
+ * @param aOperation
+ * Operation to be done.
+ * @param aUser
+ * Currently logged in user or null if no user is logged in.
+ *
+ * @return Authorization result,
+ */
+ protected AuthorizationResult isAllowed(String aPath, Operation aOperation,
+ User aUser) {
+ if (!pathCondition.matches(aPath)) {
+ return UNDECIDED;
+ }
+
+ if (!operationCondition.matches(aOperation)) {
+ return UNDECIDED;
+ }
+
+ if (!userCondition.matches(aUser)) {
+ return UNDECIDED;
+ }
+
+ return result;
+ }
+
+ /**
+ * Gets the path of the resource.
+ *
+ * @param aResource
+ * Resource, guaranteed to be an instance of
+ * {@link #resourceClass}.
+ *
+ * @return Path of the resource.
+ */
+ protected abstract String getResourcePath(Object aResource);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "UrlAUthorizationRule(result = " + result +
+ ", pathCondition = " + pathCondition + ", userCondition = " +
+ userCondition + ", resourceClass = " + resourceClass + ")";
+ }
+
+ /**
+ * Gets the authorization result for OR mapping.
+ *
+ * @return Result.
+ */
+ @Column(name = "AUTH_RESULT", nullable = false)
+ protected String getAuthorizationResultString() {
+ if (result == null) {
+ return null;
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Sets the authorization result, for OR mapping.
+ *
+ * @param aResult
+ * Result.
+ */
+ protected void setAuthorizationResultString(String aResult) {
+ result = AuthorizationResult.valueOf(aResult);
+ }
+
+ @Column(name = "RES_CLASSNAME", nullable = false)
+ protected String getResourceClassName() {
+ if (resourceClass == null) {
+ return "";
+ }
+
+ return resourceClass.getName();
+ }
+
+ protected void setResourceClassName(String aResourceClass) {
+ try {
+ resourceClass = Class.forName(aResourceClass);
+ } catch (ClassNotFoundException e) {
+ LOGGER.error("Cannot find resource class '" + aResourceClass + "'",
+ e);
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ *
+ * @return Returns the operationCondition.
+ */
+ @ManyToOne(cascade = CascadeType.ALL, targetEntity = AbstractOperationCondition.class)
+ @JoinColumn(name = "OPER_COND_PK")
+ public OperationCondition getOperationCondition() {
+ return operationCondition;
+ }
+
+ /**
+ *
+ * @param aOperationCondition
+ * The operationCondition to set.
+ */
+ protected void setOperationCondition(OperationCondition aOperationCondition) {
+ operationCondition = aOperationCondition;
+ }
+
+ /**
+ *
+ * @return Returns the pathCondition.
+ */
+ @ManyToOne(cascade = CascadeType.ALL, targetEntity = AbstractPathCondition.class)
+ @JoinColumn(name = "PATH_COND_PK")
+ public PathCondition getPathCondition() {
+ return pathCondition;
+ }
+
+ /**
+ *
+ * @param aPathCondition
+ * The pathCondition to set.
+ */
+ protected void setPathCondition(PathCondition aPathCondition) {
+ pathCondition = aPathCondition;
+ }
+
+ /**
+ *
+ * @return Returns the userCondition.
+ */
+ @ManyToOne(cascade = CascadeType.ALL, targetEntity = AbstractUserCondition.class)
+ @JoinColumn(name = "USER_COND_PK")
+ public UserCondition getUserCondition() {
+ return userCondition;
+ }
+
+ /**
+ *
+ * @param aUserCondition
+ * The userCondition to set.
+ */
+ protected void setUserCondition(UserCondition aUserCondition) {
+ userCondition = aUserCondition;
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
-import org.wamblee.persistence.Persistent;
import org.wamblee.usermgt.User;
/**
- * Condition used to match a user against a specified set of users.
- *
+ * Condition used to match a user against a specified set of users.
+ *
* @author Erik Brakkee
*/
-public interface UserCondition extends Persistent {
+public interface UserCondition {
/**
- * Determines if the condition matches.
- * @param aUser user to check.
- * @return True if the condition matches, false otherwise.
+ * Determines if the condition matches.
+ *
+ * @param aUser
+ * user to check.
+ *
+ * @return True if the condition matches, false otherwise.
*/
- boolean matches(User aUser);
-}
+ public abstract boolean matches(User aUser);
+
+}
\ No newline at end of file
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * Represents a write operation on a resource.
- *
+ * Represents a write operation on a resource.
+ *
* @author Erik Brakkee
*/
public class WriteOperation extends AllOperation {
-
private static final String OPERATION = "write";
-
+
/**
- * Constructs the operation.
- *
+ * Constructs the operation.
+ *
*/
- public WriteOperation() {
- super(OPERATION);
+ public WriteOperation() {
+ super(OPERATION);
}
-
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization.jpa;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
+
+import org.wamblee.persistence.JpaMergeSupport;
+import org.wamblee.security.authorization.AbstractAuthorizationService;
+import org.wamblee.security.authorization.AbstractAuthorizationRule;
+import org.wamblee.security.authorization.AuthorizationRule;
+import org.wamblee.security.authorization.AuthorizationService;
+import org.wamblee.security.authorization.DefaultAuthorizationService;
+import org.wamblee.security.authorization.Operation;
+import org.wamblee.usermgt.UserAccessor;
+
+/**
+ * Authorization service with persistent storage. This is a wrapper for
+ * {@link org.wamblee.security.authorization.DefaultAuthorizationService} which
+ * refreshes the state of the service at certain time intervals.
+ *
+ * @author Erik Brakkee
+ */
+public class JpaAuthorizationService implements AuthorizationService {
+
+ /**
+ * Authorization service to use.
+ */
+ private AuthorizationService service;
+
+ /**
+ * Hibernate template to use.
+ */
+ private EntityManager entityManager;
+
+ /**
+ * User accessor.
+ */
+ private UserAccessor userAccessor;
+
+ /**
+ * Name of the service.
+ */
+ private String name;
+
+ /**
+ * Refresh interval in milliseconds.
+ */
+ private final long refreshInterval;
+
+ /**
+ * Last refresh time.
+ */
+ private long lastRefreshTime;
+
+ /**
+ * Constructs the persistent service.
+ *
+ * @param aName
+ * Name of the service.
+ * @param aEntityManager
+ * Entity manager.
+ * @param aAccessor
+ * User accessor.
+ * @param aRefresh
+ * Whether or not to refresh the state of the service at the
+ * start of every operation.
+ */
+ public JpaAuthorizationService(String aName, EntityManager aEntityManager,
+ UserAccessor aAccessor, long aRefreshInterval) {
+ entityManager = aEntityManager;
+ refreshInterval = aRefreshInterval;
+ lastRefreshTime = System.currentTimeMillis();
+ userAccessor = aAccessor;
+ name = aName;
+ }
+
+ @Override
+ public void setUserAccessor(UserAccessor aUserAccessor) {
+ userAccessor = aUserAccessor;
+ }
+
+ /**
+ * Initialize service if needed.
+ *
+ */
+ private void initialize() {
+ if (service == null) {
+ refreshByReload();
+ }
+ }
+
+ private void refreshByReload() {
+ try {
+ service = entityManager.createNamedQuery(
+ AbstractAuthorizationService.QUERY_FIND_BY_NAME,
+ AbstractAuthorizationService.class).setParameter(
+ AbstractAuthorizationService.NAME_PARAM, name).getSingleResult();
+ service.setUserAccessor(userAccessor);
+ } catch (NonUniqueResultException e) {
+ throw new IllegalArgumentException(
+ "Returned more than one service for name '" + name + "'");
+ } catch (NoResultException e) {
+ service = new DefaultAuthorizationService(userAccessor, name);
+ entityManager.persist(service);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#isAllowed(java
+ * .lang.Object, org.wamblee.security.authorization.Operation)
+ */
+ public boolean isAllowed(Object aResource, Operation aOperation) {
+ initialize();
+ refresh();
+
+ return service.isAllowed(aResource, aOperation);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.security.authorization.AuthorizationService#check(T,
+ * org.wamblee.security.authorization.Operation)
+ */
+ public <T> T check(T aResource, Operation aOperation) {
+ initialize();
+ refresh();
+
+ return service.check(aResource, aOperation);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.security.authorization.AuthorizationService#getRules()
+ */
+ public AuthorizationRule[] getRules() {
+ initialize();
+ refresh();
+
+ return service.getRules();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#appendRule(org
+ * .wamblee.security.authorization.AuthorizationRule)
+ */
+ public void appendRule(AuthorizationRule aRule) {
+ initialize();
+ refresh();
+ service.appendRule(aRule);
+ save();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#removeRule(int)
+ */
+ public void removeRule(int aIndex) {
+ initialize();
+ refresh();
+ service.removeRule(aIndex);
+ save();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationService#insertRuleAfter
+ * (int, org.wamblee.security.authorization.AuthorizationRule)
+ */
+ public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
+ initialize();
+ refresh();
+ service.insertRuleAfter(aIndex, aRule);
+ save();
+ }
+
+ /**
+ * Refreshes the state of the service through hibernate.
+ */
+ private synchronized void refresh() {
+ long time = System.currentTimeMillis();
+
+ if ((time - lastRefreshTime) > refreshInterval) {
+ refreshByReload();
+ lastRefreshTime = time;
+ }
+ }
+
+ /**
+ * Saves any changes to the service state if necessary.
+ */
+ private void save() {
+ AuthorizationService merged = entityManager.merge(service);
+ entityManager.flush();
+ JpaMergeSupport.merge(merged, service);
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.security.encryption;
+import org.apache.commons.codec.binary.Hex;
+
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import org.apache.commons.codec.binary.Hex;
-
/**
- * MD5 Hex encoder.
- *
+ * MD5 Hex encoder.
+ *
* @author Erik Brakkee
*/
public class Md5HexMessageDigester implements MessageDigester {
-
/**
- * Constructs the message digester.
- *
+ * Constructs the message digester.
+ *
*/
public Md5HexMessageDigester() {
// Empty
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] result = digest.digest(aValue.getBytes());
char[] charResult = Hex.encodeHex(result);
+
return new String(charResult);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("MD5 not supported????");
}
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.encryption;
/**
- * Utility class that encapsulates a message digest method.
+ * Utility class that encapsulates a message digest method.
*/
public interface MessageDigester {
-
/**
- * Computes a message digest for a value and encodes it in some way.
- * @param aValue Value to compute digest for.
- * @return Encoded digest.
+ * Computes a message digest for a value and encodes it in some way.
+ *
+ * @param aValue
+ * Value to compute digest for.
+ *
+ * @return Encoded digest.
*/
- String hash(String aValue);
-
+ String hash(String aValue);
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
-import static org.wamblee.usermgt.UserMgtException.Reason.DUPLICATE_USER;
-
import org.wamblee.security.encryption.MessageDigester;
+import static org.wamblee.usermgt.UserMgtException.Reason.DUPLICATE_USER;
/**
- * User set base class.
+ * User set base class.
*/
public abstract class AbstractUserSet implements UserSet {
-
/**
- * Password validator.
+ * Password validator.
*/
- private NameValidator _passwordValidator;
-
+ private NameValidator passwordValidator;
+
/**
- * Password encoder.
+ * Password encoder.
*/
- private MessageDigester _passwordEncoder;
+ private MessageDigester passwordEncoder;
-
- protected AbstractUserSet(NameValidator aPasswordValidator,
- MessageDigester aPasswordEncoder) {
- _passwordValidator = aPasswordValidator;
- _passwordEncoder = aPasswordEncoder;
+ /**
+ * Creates a new AbstractUserSet object.
+ *
+ */
+ protected AbstractUserSet(NameValidator aPasswordValidator,
+ MessageDigester aPasswordEncoder) {
+ passwordValidator = aPasswordValidator;
+ passwordEncoder = aPasswordEncoder;
}
-
+
/**
- * Sets the password validtor and encoder in the user.
- * @param aUser User.
+ * Sets the password validtor and encoder in the user.
+ *
+ * @param aUser
+ * User.
*/
- protected void setPasswordInfo(User aUser) {
- aUser.setPasswordValidator(_passwordValidator);
- aUser.setPasswordEncoder(_passwordEncoder);
+ protected void setPasswordInfo(User aUser) {
+ aUser.setPasswordValidator(passwordValidator);
+ aUser.setPasswordEncoder(passwordEncoder);
}
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.UserSet#createUser(java.lang.String, java.lang.String, org.wamblee.usermgt.Group)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.UserSet#createUser(java.lang.String,
+ * java.lang.String, org.wamblee.usermgt.Group)
*/
- public User createUser(String aUsername, String aPassword, Group aGroup) throws UserMgtException {
- User user = new User(aUsername, aPassword, aGroup, _passwordValidator, _passwordEncoder);
+ public User createUser(String aUsername, String aPassword, Group aGroup)
+ throws UserMgtException {
+ User user = new User(aUsername, aPassword, aGroup, passwordValidator,
+ passwordEncoder);
+
if (contains(user)) {
throw new UserMgtException(DUPLICATE_USER, user);
}
+
add(user);
+
return user;
}
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+/**
+ * Represents a group.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@Table(name = "SEC_GROUP")
+@NamedQueries( {
+ @NamedQuery(name = Group.QUERY_FIND_BY_NAME, query = "select g from Group g where g.name = :" +
+ Group.NAME_PARAM),
+ @NamedQuery(name = Group.QUERY_COUNT_GROUPS, query = "select count(g) from Group g"),
+ @NamedQuery(name = Group.QUERY_ALL_GROUPS, query = "select g from Group g") })
+public class Group implements Serializable, Comparable {
+
+ public static final String QUERY_FIND_BY_NAME = "Group.findByName";
+ public static final String QUERY_COUNT_GROUPS = "Group.count";
+ public static final String QUERY_ALL_GROUPS = "Group.all";
+ public static final String NAME_PARAM = "name";
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ /**
+ * Group name.
+ */
+ @Column(nullable = false, unique = true)
+ private String name;
+
+ /**
+ * Constructs the group.
+ *
+ * @param aName
+ */
+ Group(String aName) {
+ super();
+ name = aName;
+ }
+
+ /**
+ * Creates a new Group object.
+ *
+ */
+ public Group(Group aGroup) {
+ primaryKey = aGroup.primaryKey;
+ version = aGroup.version;
+ name = aGroup.name;
+ }
+
+ /**
+ * Creates a new Group object.
+ */
+ protected Group() {
+ super();
+ name = null;
+ }
+
+ /**
+ * Gets the name of the group.
+ *
+ * @return Group name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the group name.
+ *
+ * @param aName
+ * Group name.
+ */
+ void setName(String aName) {
+ name = aName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object aGroup) {
+ if (aGroup == null) {
+ return false;
+ }
+ if (!(aGroup instanceof Group)) {
+ return false;
+ }
+
+ return name.equals(((Group) aGroup).name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(T)
+ */
+ public int compareTo(Object aGroup) {
+ return name.compareTo(((Group) aGroup).name);
+ }
+
+ public Long getPrimaryKey() {
+ return primaryKey;
+ }
+
+ public void setPrimaryKey(Long aKey) {
+ primaryKey = aKey;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Group(pk = " + getPrimaryKey() + ", name=" + name + ")";
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
import java.util.Set;
/**
- * Represents a set of groups. A typical implemnetation would be, a readonly implementation
- * defined in a configuration file or a list of groups defined in a database.
- *
+ * Represents a set of groups. A typical implemnetation would be, a readonly
+ * implementation defined in a configuration file or a list of groups defined in
+ * a database.
+ *
* @author Erik Brakkee
*/
public interface GroupSet {
-
/**
- * Must be called when the group has been modified to notify the group set.
- * @param aGroup Group that was modified.
+ * Must be called when the group has been modified to notify the group set.
+ *
+ * @param aGroup
+ * Group that was modified.
*/
- void groupModified(Group aGroup);
-
+ void groupModified(Group aGroup);
+
/**
- * Finds the group by name.
- * @param aName Group name.
- * @return Group or null if not found.
+ * Finds the group by name.
+ *
+ * @param aName
+ * Group name.
+ *
+ * @return Group or null if not found.
*/
Group find(String aName);
-
+
/**
- * Determines if the group exists.
- * @param aGroup Group.
- * @return True iff the group exists.
+ * Determines if the group exists.
+ *
+ * @param aGroup
+ * Group.
+ *
+ * @return True iff the group exists.
*/
boolean contains(Group aGroup);
-
+
/**
- * Adds a group. If the group already exists, the existing group set
- * is left unchanged.
- * @param aGroup Group.
+ * Adds a group. If the group already exists, the existing group set is left
+ * unchanged.
+ *
+ * @param aGroup
+ * Group.
+ *
*/
boolean add(Group aGroup);
-
+
/**
- * Removes a group. If the group does not exist, this method is a no-op.
- * @param aGroup Group to remove.
- * @return True if the group was removed, false otherwise.
+ * Removes a group. If the group does not exist, this method is a no-op.
+ *
+ * @param aGroup
+ * Group to remove.
+ *
+ * @return True if the group was removed, false otherwise.
*/
boolean remove(Group aGroup);
-
+
/**
- * Returns the current groups.
- * @return Groups.
+ * Returns the current groups.
+ *
+ * @return Groups.
*/
Set<Group> list();
/**
- * @return The number of groups.
+ *
+ * @return The number of groups.
*/
- int size();
+ int size();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.usermgt;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicLong;
/**
- * In-memory group set implementation.
- *
+ * In-memory group set implementation.
+ *
* @author Erik Brakkee
*/
public class InMemoryGroupSet implements GroupSet {
-
+
+ private AtomicLong pk = new AtomicLong(1l);
+
/**
- * Groups.
+ * Groups.
*/
- private Set<Group> _groups;
-
+ private List<Group> groups;
+
/**
- * Constructs an empty group set.
+ * Constructs an empty group set.
*/
- public InMemoryGroupSet() {
- _groups = new TreeSet<Group>();
+ public InMemoryGroupSet() {
+ groups = new ArrayList<Group>();
}
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#groupModified(org.wamblee.usermgt.Group)
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.usermgt.GroupSet#groupModified(org.wamblee.usermgt.Group)
*/
public void groupModified(Group aGroup) {
- _groups.remove(aGroup);
- _groups.add(aGroup);
+ for (int i = 0; i < groups.size(); i++) {
+ if (groups.get(i).getPrimaryKey().equals(aGroup.getPrimaryKey())) {
+ groups.remove(i);
+ groups.add(aGroup);
+ return;
+ }
+ }
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.GroupSet#find(java.lang.String)
*/
public Group find(String aName) {
- for (Group group: _groups) {
- if ( group.getName().equals(aName)) {
- return new Group(group);
+ for (Group group : groups) {
+ if (group.getName().equals(aName)) {
+ return group;
}
}
- return null;
+
+ return null;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.GroupSet#contains(org.wamblee.usermgt.Group)
*/
public boolean contains(Group aGroup) {
- return _groups.contains(aGroup);
+ return groups.contains(aGroup);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.GroupSet#add(org.wamblee.usermgt.Group)
*/
public boolean add(Group aGroup) {
- return _groups.add(aGroup);
+ aGroup.setPrimaryKey(pk.getAndIncrement());
+ if (find(aGroup.getName()) != null) {
+ return false;
+ }
+ return groups.add(aGroup);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.GroupSet#remove(org.wamblee.usermgt.Group)
*/
public boolean remove(Group aGroup) {
- return _groups.remove(aGroup);
+ return groups.remove(aGroup);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.GroupSet#list()
*/
public Set<Group> list() {
- Set<Group> list = new TreeSet<Group>();
- for (Group group: _groups) {
+ Set<Group> list = new TreeSet<Group>();
+
+ for (Group group : groups) {
list.add(new Group(group));
}
+
return list;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.GroupSet#size()
*/
public int size() {
- return _groups.size();
+ return groups.size();
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.usermgt;
+import org.wamblee.security.encryption.MessageDigester;
+
import java.util.Set;
import java.util.TreeSet;
-import org.wamblee.security.encryption.MessageDigester;
-
/**
* In-memory user set.
- *
+ *
* @author Erik Brakkee
*/
public class InMemoryUserSet extends AbstractUserSet {
-
/**
- * Users. All users in this set have their password validator and encoder set.
+ * Users. All users in this set have their password validator and encoder
+ * set.
*/
- private Set<User> _users;
+ private Set<User> users;
/**
* Constructs an empty user set.
*/
- public InMemoryUserSet(NameValidator aPasswordValidator, MessageDigester aPasswordEncoder) {
+ public InMemoryUserSet(NameValidator aPasswordValidator,
+ MessageDigester aPasswordEncoder) {
super(aPasswordValidator, aPasswordEncoder);
- _users = new TreeSet<User>();
+ users = new TreeSet<User>();
}
/*
* @see org.wamblee.usermgt.UserSet#userModified(org.wamblee.usermgt.User)
*/
public void userModified(User aUser) {
- _users.remove(aUser);
- setPasswordInfo(aUser);
- _users.add(aUser);
+ users.remove(aUser);
+ setPasswordInfo(aUser);
+ users.add(aUser);
}
/*
* @see org.wamblee.usermgt.UserSet#find(java.lang.String)
*/
public User find(String aName) {
- for (User user : _users) {
+ for (User user : users) {
if (user.getName().equals(aName)) {
return new User(user);
}
}
+
return null;
}
*/
public boolean add(User aUser) {
setPasswordInfo(aUser);
- return _users.add(aUser);
+
+ return users.add(aUser);
}
/*
* @see org.wamblee.usermgt.UserSet#contains(org.wamblee.usermgt.User)
*/
public boolean contains(User aUser) {
- return _users.contains(aUser);
+ return users.contains(aUser);
}
/*
* @see org.wamblee.usermgt.UserSet#remove(org.wamblee.usermgt.User)
*/
public boolean remove(User aUser) {
- return _users.remove(aUser);
+ return users.remove(aUser);
}
/*
*/
public Set<User> list() {
Set<User> list = new TreeSet<User>();
- for (User user : _users) {
+
+ for (User user : users) {
list.add(new User(user));
}
+
return list;
}
*/
public Set<User> list(Group aGroup) {
Set<User> result = new TreeSet<User>();
- for (User user : _users) {
+
+ for (User user : users) {
if (user.getGroups().contains(aGroup)) {
result.add(new User(user));
}
}
+
return result;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.UserSet#size()
*/
public int size() {
- return _users.size();
+ return users.size();
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.usermgt;
import java.security.AccessController;
import java.security.Principal;
+
import java.util.Set;
import javax.security.auth.Subject;
/**
- * Implementation of the user accessor that retrieves user information
- * from JAAS.
- *
+ * Implementation of the user accessor that retrieves user information from
+ * JAAS.
+ *
* @author Erik Brakkee
*/
public class JaasUserAccessor implements UserAccessor {
-
/**
- * User administration to use.
+ * User administration to use.
*/
- private UserAdministration _admin;
+ private UserAdministration admin;
/**
- * Class of the JAAS user principal.
+ * Class of the JAAS user principal.
*/
- private Class _userPrincipalClass;
+ private Class userPrincipalClass;
/**
- * Constructs user accessor.
- * @param aAdmin User administration.
- * @param aUserClassName Class name of the user principal.
+ * Constructs user accessor.
+ *
+ * @param aAdmin
+ * User administration.
+ * @param aUserClassName
+ * Class name of the user principal.
*/
public JaasUserAccessor(UserAdministration aAdmin, String aUserClassName) {
- _admin = aAdmin;
+ admin = aAdmin;
+
try {
- _userPrincipalClass = Class.forName(aUserClassName);
- if ( !Principal.class.isAssignableFrom(_userPrincipalClass)) {
- throw new IllegalArgumentException("Specified class '" + aUserClassName + "' is not a subclass of '" +
- Principal.class.getName());
+ userPrincipalClass = Class.forName(aUserClassName);
+
+ if (!Principal.class.isAssignableFrom(userPrincipalClass)) {
+ throw new IllegalArgumentException("Specified class '" +
+ aUserClassName + "' is not a subclass of '" +
+ Principal.class.getName());
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
*/
public User getCurrentUser() {
Subject subject = Subject.getSubject(AccessController.getContext());
+
if (subject == null) {
return null;
}
+
Principal userPrincipal = getUserPrincipal(subject);
-
- return _admin.getUser(userPrincipal.getName());
+
+ return admin.getUser(userPrincipal.getName());
}
/**
- * Gets the user principal from the subject.
- * @param subject Subject.
- * @return User principal.
- * @throws IllegalArgumentException In case there is a duplicate principal or the principal was not found.
+ * Gets the user principal from the subject.
+ *
+ * @param aSubject
+ * Subject.
+ *
+ * @return User principal.
+ *
+ * @throws IllegalArgumentException
+ * In case there is a duplicate principal or the principal was
+ * not found.
*/
- private Principal getUserPrincipal(Subject subject) {
- Set<Principal> principals = subject.getPrincipals();
- Principal userPrincipal = null;
- for ( Principal principal: principals) {
- if ( principal.getClass().equals(_userPrincipalClass)) {
- if ( userPrincipal != null ) {
+ private Principal getUserPrincipal(Subject aSubject) {
+ Set<Principal> principals = aSubject.getPrincipals();
+ Principal userPrincipal = null;
+
+ for (Principal principal : principals) {
+ if (principal.getClass().equals(userPrincipalClass)) {
+ if (userPrincipal != null) {
throw new IllegalArgumentException(
- "Multiple principals for class '" + _userPrincipalClass + "', subject: " + subject);
+ "Multiple principals for class '" + userPrincipalClass +
+ "', subject: " + aSubject);
}
- userPrincipal = principal;
+
+ userPrincipal = principal;
}
}
- if ( userPrincipal == null ) {
+
+ if (userPrincipal == null) {
throw new IllegalArgumentException(
- "No user principal found for class '" + _userPrincipalClass + "', subject: " + subject);
+ "No user principal found for class '" + userPrincipalClass +
+ "', subject: " + aSubject);
}
+
return userPrincipal;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
/**
* Validator of names.
- *
+ *
* @author Erik Brakkee
*/
public interface NameValidator {
-
/**
- * Validates a name.
- * @param aName Name
- * @throws UserMgtException In case the name is invalid.
+ * Validates a name.
+ *
+ * @param aName
+ * Name
+ *
+ * @throws UserMgtException
+ * In case the name is invalid.
*/
- void validate(String aName) throws UserMgtException;
+ void validate(String aName) throws UserMgtException;
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
import org.wamblee.usermgt.UserMgtException.Reason;
/**
- * Validation of names based on a regular expression.
- *
+ * Validation of names based on a regular expression.
+ *
* @author Erik Brakkee
*/
public class RegexpNameValidator implements NameValidator {
-
/**
- * Convenience pattern for an id.
+ * Convenience pattern for an id.
*/
public static final String ID_PATTERN = "[a-zA-Z]+[a-zA-Z0-9]*";
-
+
/**
- * Convenience pattern for a password consisting of at least 6 characters.
+ * Convenience pattern for a password consisting of at least 6 characters.
*/
public static final String PASSWORD_PATTERN = ".{6}.*";
-
+
/**
- * Pattern to use.
+ * Pattern to use.
*/
- private String _pattern;
-
+ private String pattern;
+
/**
- * Reason to use when validation fails.
+ * Reason to use when validation fails.
*/
- private Reason _reason;
-
+ private Reason reason;
+
/**
- * Message to report.
+ * Message to report.
*/
- private String _message;
-
+ private String message;
+
/**
- * Validates a regular expression.
- * @param aPattern Pattern that names must comply to.
- * @param aReason Reason to report when validation fails.
- * @param aMessage Message to report.
+ * Validates a regular expression.
+ *
+ * @param aPattern
+ * Pattern that names must comply to.
+ * @param aReason
+ * Reason to report when validation fails.
+ * @param aMessage
+ * Message to report.
*/
- public RegexpNameValidator(String aPattern, Reason aReason, String aMessage) {
- _pattern = aPattern;
- _reason = aReason;
- _message = aMessage;
+ public RegexpNameValidator(String aPattern, Reason aReason, String aMessage) {
+ pattern = aPattern;
+ reason = aReason;
+ message = aMessage;
}
-
+
/**
- * Convenience constructor with all string parameters. Useful for configuration
- * in Spring.
- * @param aPattern Pattern to use.
- * @param aReason Reason.
- * @param aMessage Message.
+ * Convenience constructor with all string parameters. Useful for
+ * configuration in Spring.
+ *
+ * @param aPattern
+ * Pattern to use.
+ * @param aReason
+ * Reason.
+ * @param aMessage
+ * Message.
*/
- public RegexpNameValidator(String aPattern, String aReason, String aMessage) {
+ public RegexpNameValidator(String aPattern, String aReason, String aMessage) {
this(aPattern, Reason.valueOf(aReason), aMessage);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.NameValidator#validate(java.lang.String)
*/
public void validate(String aName) throws UserMgtException {
- if ( !aName.matches(_pattern)) {
- throw new UserMgtException(_reason, _message);
+ if (!aName.matches(pattern)) {
+ throw new UserMgtException(reason, message);
}
}
-
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt;
+
+import java.io.Serializable;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.Version;
+
+import org.wamblee.security.encryption.MessageDigester;
+import org.wamblee.usermgt.UserMgtException.Reason;
+
+/**
+ * Represents a user. The methods for managing the groups of the user have
+ * package scope. Managing the groups of the user should be done through the
+ * {@link org.wamblee.usermgt.UserAdministration} interface.
+ */
+@Entity
+@Table(name = "SEC_USER")
+@NamedQueries( {
+ @NamedQuery(name = User.QUERY_FIND_BY_NAME, query = "select u from User u where u.name = :" +
+ User.NAME_PARAM),
+ @NamedQuery(name = User.QUERY_FIND_BY_GROUP_NAME, query = "select user from User user join user.groups grp where grp.name = :name"),
+ @NamedQuery(name = User.QUERY_COUNT_USERS, query = "select count(u) from User u"),
+ @NamedQuery(name = User.QUERY_ALL_USERS, query = "select u from User u")})
+public class User implements Serializable, Comparable {
+
+ public static final String QUERY_FIND_BY_NAME = "User.findByName";
+ public static final String QUERY_FIND_BY_GROUP_NAME = "User.findByGroupName";
+ public static final String QUERY_COUNT_USERS = "User.count";
+ public static final String QUERY_ALL_USERS = "User.all";
+ public static final String NAME_PARAM = "name";
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long primaryKey;
+
+ @Version
+ private int version;
+
+ /**
+ * User name.
+ */
+ private String name;
+
+ /**
+ * Password.
+ */
+ private String password;
+
+ /**
+ * Groups the user belongs to.
+ */
+ @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
+ private Set<Group> groups;
+
+ /**
+ * Password validator.
+ */
+ @Transient
+ private NameValidator passwordValidator;
+
+ /**
+ * Password encoder.
+ */
+ @Transient
+ private MessageDigester passwordEncoder;
+
+ /**
+ * Constructs the user.
+ *
+ * @param aName
+ * User name.
+ * @param aPassword
+ * Password.
+ * @param aGroup
+ * Group the user belongs to.
+ */
+ User(String aName, String aPassword, Group aGroup,
+ NameValidator aPasswordValidator, MessageDigester aPasswordEncoder)
+ throws UserMgtException {
+ super();
+ name = aName;
+ aPasswordValidator.validate(aPassword);
+ password = aPasswordEncoder.hash(aPassword);
+ groups = new TreeSet<Group>();
+ groups.add(aGroup);
+ passwordValidator = aPasswordValidator;
+ passwordEncoder = aPasswordEncoder;
+ }
+
+ /**
+ * Creates a new User object.
+ *
+ */
+ public User(User aUser) {
+ primaryKey = aUser.primaryKey;
+ version = aUser.version;
+ name = aUser.name;
+ password = aUser.password;
+ groups = new TreeSet<Group>();
+
+ for (Group group : aUser.groups) {
+ groups.add(new Group(group));
+ }
+
+ passwordValidator = aUser.passwordValidator;
+ passwordEncoder = aUser.passwordEncoder;
+ }
+
+ /**
+ * Creates a new User object.
+ */
+ User() {
+ super();
+ name = null;
+ password = null;
+ groups = null;
+ passwordValidator = null;
+ passwordEncoder = null;
+ }
+
+ /**
+ * Sets the password validator.
+ *
+ * @param aPasswordValidator
+ * Validator.
+ */
+ public void setPasswordValidator(NameValidator aPasswordValidator) {
+ passwordValidator = aPasswordValidator;
+ }
+
+ /**
+ * Sets the password encoder.
+ *
+ * @param aPasswordEncoder
+ * Encoder.
+ */
+ public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
+ passwordEncoder = aPasswordEncoder;
+ }
+
+ /**
+ *
+ * @return Returns the password.
+ */
+ String getPassword() {
+ return password;
+ }
+
+ /**
+ * Checks the password.
+ *
+ * @param aPassword
+ * Password to check.
+ *
+ * @throws UserMgtException
+ * In case the password is incorrect.
+ */
+ public void checkPassword(String aPassword) throws UserMgtException {
+ String encoded = passwordEncoder.hash(aPassword);
+
+ if (!password.equals(encoded)) {
+ throw new UserMgtException(Reason.INVALID_PASSWORD, this);
+ }
+ }
+
+ /**
+ * Changes the password.
+ *
+ * @param aOldPassword
+ * Old password.
+ * @param aNewPassword
+ * New password.
+ *
+ * @throws UserMgtException
+ * In case the old password is incorrect.
+ */
+ public void changePassword(String aOldPassword, String aNewPassword)
+ throws UserMgtException {
+ checkPassword(aOldPassword);
+ passwordValidator.validate(aNewPassword);
+ setPassword(aNewPassword);
+ }
+
+ /**
+ *
+ * @param aPassword
+ * The password to set.
+ *
+ */
+ public void setPassword(String aPassword) throws UserMgtException {
+ passwordValidator.validate(aPassword);
+ password = passwordEncoder.hash(aPassword);
+ }
+
+ /**
+ * For OR mapping.
+ *
+ * @return Password.
+ */
+ protected String getPasswordString() {
+ return password;
+ }
+
+ /**
+ * For OR mapping.
+ *
+ * @param aPassword
+ * Password.
+ */
+ protected void setPasswordString(String aPassword) {
+ password = aPassword;
+ }
+
+ /**
+ *
+ * @return Returns the _user.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ *
+ * @param aName
+ * The username to set.
+ */
+ void setName(String aName) {
+ name = aName;
+ }
+
+ /**
+ * Gets the groups the user belongs to.
+ *
+ * @return Groups.
+ */
+ public Set<Group> getGroups() {
+ Set<Group> result = new TreeSet<Group>();
+ result.addAll(groups);
+
+ return result;
+ }
+
+ /**
+ * Checks whether the user belongs to the given group.
+ *
+ * @param aGroup
+ * Group.
+ *
+ * @return True if the user belongs to the group.
+ */
+ public boolean isInGroup(Group aGroup) {
+ return groups.contains(aGroup);
+ }
+
+ /**
+ * Checks whether the user belongs to the given group.
+ *
+ * @param aGroup
+ * Group.
+ *
+ * @return True if the user belongs to the group.
+ */
+ public boolean isInGroup(String aGroup) {
+ return groups.contains(new Group(aGroup));
+ }
+
+ /**
+ * Gets the group set. For OR mapping.
+ *
+ * @return set of groups.
+ */
+ Set<Group> getGroupSet() {
+ return groups;
+ }
+
+ /**
+ * Sets the groups the user belongs to, for OR mapping.
+ *
+ * @param aGroups
+ * Groups.
+ */
+ void setGroupSet(Set<Group> aGroups) {
+ groups = aGroups;
+ }
+
+ /**
+ * Adds the user to a group.
+ *
+ * @param aGroup
+ * Group to add the user to.
+ *
+ * @throws UserMgtException
+ * In case the user already belongs to the group.
+ */
+ void addGroup(Group aGroup) throws UserMgtException {
+ if (groups.contains(aGroup)) {
+ throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
+ }
+
+ groups.add(aGroup);
+ }
+
+ /**
+ * Removes the user from a group.
+ *
+ * @param aGroup
+ * Group.
+ *
+ * @throws UserMgtException
+ * In case the user does not belong to the group.
+ */
+ void removeGroup(Group aGroup) throws UserMgtException {
+ if (!groups.contains(aGroup)) {
+ throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
+ }
+
+ if (groups.size() == 1) {
+ throw new UserMgtException(Reason.USER_MUST_BE_IN_A_GROUP, this,
+ aGroup);
+ }
+
+ groups.remove(aGroup);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object aUser) {
+ if (!(aUser instanceof User)) {
+ return false;
+ }
+
+ User user = (User) aUser;
+
+ return name.equals(user.name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ String result = "User(name=" + name + ", password=" + password;
+
+ for (Group group : groups) {
+ result += (", group=" + group);
+ }
+
+ return result + ")";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(T)
+ */
+ public int compareTo(Object aUser) {
+ return name.compareTo(((User) aUser).name);
+ }
+
+ public Long getPrimaryKey() {
+ return primaryKey;
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
/**
- * Interface for accessing the currently logged in user.
- *
+ * Interface for accessing the currently logged in user.
+ *
* @author Erik Brakkee
*/
public interface UserAccessor {
/**
- * Gets the current user.
- * @return Currently logged in user or null if no user is found.
+ * Gets the current user.
+ *
+ * @return Currently logged in user or null if no user is found.
*/
- User getCurrentUser();
+ User getCurrentUser();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.usermgt;
-import java.security.NoSuchAlgorithmException;
-
import org.apache.log4j.Logger;
+import java.security.NoSuchAlgorithmException;
+
/**
* User administration initializer. It populates the user administration with a
* number of groups and users but only in case no users exist.
- *
+ *
* @author Erik Brakkee
*/
public class UserAdminInitializer {
-
- private static final Logger LOGGER = Logger.getLogger(UserAdminInitializer.class);
-
+ private static final Logger LOGGER = Logger
+ .getLogger(UserAdminInitializer.class);
+
/**
* Initializes the user administration in case no users are present.
*
*/
public UserAdminInitializer(UserAdministration aAdmin, String[] aUsers,
- String[] aGroups, String[] aPasswords) throws UserMgtException, NoSuchAlgorithmException {
- if (aUsers.length != aGroups.length
- || aUsers.length != aPasswords.length) {
+ String[] aGroups, String[] aPasswords) throws UserMgtException,
+ NoSuchAlgorithmException {
+ if ((aUsers.length != aGroups.length) ||
+ (aUsers.length != aPasswords.length)) {
throw new IllegalArgumentException(
- "Array sizes for users, groups, and passwords differ: "
- + aUsers.length + "," + aGroups.length + ","
- + aPasswords.length);
-
+ "Array sizes for users, groups, and passwords differ: " +
+ aUsers.length + "," + aGroups.length + "," +
+ aPasswords.length);
}
+
if (aAdmin.getUserCount() == 0) {
initialize(aAdmin, aUsers, aGroups, aPasswords);
}
-
}
/**
- * Adds the specified users and groups to the user administration.
- * @param aAdmin User administration.
- * @param aUsers Users.
- * @param aGroups Groups.
- * @param aPasswords Passwords.
- * @throws UserMgtException In case of a problem creating users or groups.
+ * Adds the specified users and groups to the user administration.
+ *
+ * @param aAdmin
+ * User administration.
+ * @param aUsers
+ * Users.
+ * @param aGroups
+ * Groups.
+ * @param aPasswords
+ * Passwords.
+ *
+ * @throws UserMgtException
+ * In case of a problem creating users or groups.
*/
private void initialize(UserAdministration aAdmin, String[] aUsers,
- String[] aGroups, String[] aPasswords) throws UserMgtException {
+ String[] aGroups, String[] aPasswords) throws UserMgtException {
for (int i = 0; i < aUsers.length; i++) {
String user = aUsers[i];
String group = aGroups[i];
String password = aPasswords[i];
-
+
if (aAdmin.getUser(user) == null) {
// must create user.
Group groupObj = aAdmin.getGroup(group);
+
if (groupObj == null) {
// must create group
LOGGER.info("Creating group: " + group);
groupObj = aAdmin.createGroup(group);
}
- assert groupObj != null;
-
- LOGGER.info("Creating user: " + user + " password: " + password);
+ assert groupObj != null;
+
+ LOGGER
+ .info("Creating user: " + user + " password: " + password);
aAdmin.createUser(user, password, groupObj);
}
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt;
+
+import java.util.Set;
+
+/**
+ * Interface for user administration. Manages the users and groups.
+ *
+ * @author Erik Brakkee
+ */
+public interface UserAdministration {
+ /**
+ * Creates a new user.
+ *
+ * @param aUser
+ * Username.
+ * @param aPassword
+ * Password.
+ * @param aGroup
+ * Group.
+ *
+ * @return User.
+ *
+ * @throws UserMgtException
+ * In case there is a conflict with an existing user.
+ */
+ User createUser(String aUser, String aPassword, Group aGroup)
+ throws UserMgtException;
+
+ /**
+ * Creates a new group.
+ *
+ * @param aName
+ * Group name.
+ *
+ * @return Group
+ *
+ * @throws UserMgtException
+ * In case there is a conflict with an existing group.
+ */
+ Group createGroup(String aName) throws UserMgtException;
+
+ /**
+ *
+ * @return Number of users.
+ */
+ int getUserCount();
+
+ /**
+ *
+ * @return Number of groups.
+ */
+ int getGroupCount();
+
+ /**
+ * Must be called when the user is modified.
+ *
+ * @param aUser
+ * User.
+ * @return The modified user. The user passed in to this call should be considered invalid.
+ */
+ void userModified(User aUser);
+
+ /**
+ * Must be called when the group is modified.
+ *
+ * @param aGroup
+ * Group.
+ */
+ void groupModified(Group aGroup);
+
+ /**
+ * Gets the user for a given name.
+ *
+ * @param aName
+ * User name.
+ *
+ * @return User or null if not found.
+ */
+ User getUser(String aName);
+
+ /**
+ * Gets the group for a given group name.
+ *
+ * @param aName
+ * Group name.
+ *
+ * @return Group or null if not found.
+ */
+ Group getGroup(String aName);
+
+ /**
+ * Get the users.
+ *
+ * @return All known users.
+ */
+ Set<User> getUsers();
+
+ /**
+ * Gets the users for a given group.
+ *
+ * @param aGroup
+ * Group.
+ * @return Set of users (always non-null).
+ */
+ Set<User> getUsers(Group aGroup);
+
+ /**
+ * Gets all known groups.
+ *
+ * @return Groups.
+ */
+ Set<Group> getGroups();
+
+ /**
+ * Renames a user.
+ *
+ * @param aUser
+ * User object for which user name must be changed.
+ * @param aUserName
+ * New user name.
+ *
+ * @throws UserMgtException
+ * In case the user is not known or the new user name is already
+ * in use by another user.
+ */
+ void renameUser(User aUser, String aUserName) throws UserMgtException;
+
+ /**
+ * Renames a group.
+ *
+ * @param aGroup
+ * Group to rename.
+ * @param aGroupName
+ * New name for the group.
+ *
+ * @throws UserMgtException
+ * In case the new group name is already used by another group
+ * of if the existing group is unknown.
+ */
+ void renameGroup(Group aGroup, String aGroupName) throws UserMgtException;
+
+ /**
+ * Removes the user.
+ *
+ * @param aUser
+ * User to remove.
+ *
+ * @throws UserMgtException
+ * In case the user does not exist.
+ */
+ void removeUser(User aUser) throws UserMgtException;
+
+ /**
+ * Removes the group.
+ *
+ * @param aGroup
+ * Group to remove.
+ *
+ * @throws UserMgtException
+ * In case there are still users that are in the given group.
+ */
+ void removeGroup(Group aGroup) throws UserMgtException;
+
+ /**
+ * Adds a user to a group.
+ *
+ * @param aUser
+ * User.
+ * @param aGroup
+ * Group.
+ *
+ * @throws UserMgtException
+ * In case the user or group or not known or if the user is
+ * already part of the group.
+ */
+ void addUserToGroup(User aUser, Group aGroup) throws UserMgtException;
+
+ /**
+ * Removes a user from a group.
+ *
+ * @param aUser
+ * User
+ * @param aGroup
+ * Group
+ *
+ * @throws UserMgtException
+ * In case the user or group are unknown or if the user is not
+ * part of the group.
+ */
+ void removeUserFromGroup(User aUser, Group aGroup) throws UserMgtException;
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.usermgt;
import static org.wamblee.usermgt.UserMgtException.Reason.DUPLICATE_GROUP;
/**
* Administration of users and groups.
- *
+ *
* @author Erik Brakkee
*/
public class UserAdministrationImpl implements UserAdministration {
-
/**
* All known users.
*/
- private UserSet _users;
+ private UserSet users;
/**
* All known groups.
*/
- private GroupSet _groups;
-
+ private GroupSet groups;
+
/**
- * Validator for user names.
+ * Validator for user names.
*/
- private NameValidator _userValidator;
-
+ private NameValidator userValidator;
+
/**
- * Validator for group names.
+ * Validator for group names.
*/
- private NameValidator _groupValidator;
-
+ private NameValidator groupValidator;
+
/**
* Constructs empty user administration.
*
*/
- public UserAdministrationImpl(UserSet aUsers, GroupSet aGroups, NameValidator aUserValidator,
- NameValidator aGroupValidator) {
- _users = aUsers;
- _groups = aGroups;
- _userValidator = aUserValidator;
- _groupValidator = aGroupValidator;
+ public UserAdministrationImpl(UserSet aUsers, GroupSet aGroups,
+ NameValidator aUserValidator, NameValidator aGroupValidator) {
+ users = aUsers;
+ groups = aGroups;
+ userValidator = aUserValidator;
+ groupValidator = aGroupValidator;
}
/*
* (non-Javadoc)
*
* @see org.wamblee.usermgt.UserAdministration#createUser(java.lang.String,
- * java.lang.String)
+ * java.lang.String)
*/
public User createUser(String aUser, String aPassword, Group aGroup)
- throws UserMgtException {
- _userValidator.validate(aUser);
+ throws UserMgtException {
+ userValidator.validate(aUser);
checkGroup(aGroup);
- User user = _users.createUser(aUser, aPassword, aGroup);
+
+ User user = users.createUser(aUser, aPassword, aGroup);
+
return new User(user);
}
-
+
/*
* (non-Javadoc)
*
* @see org.wamblee.usermgt.UserAdministration#createGroup(java.lang.String)
*/
public Group createGroup(String aName) throws UserMgtException {
- _groupValidator.validate(aName);
+ groupValidator.validate(aName);
+
Group group = new Group(aName);
- if (_groups.contains(group)) {
+
+ if (groups.contains(group)) {
throw new UserMgtException(DUPLICATE_GROUP, group);
}
- _groups.add(group);
+
+ groups.add(group);
+
return new Group(group);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#userModified(org.wamblee.usermgt.User)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#userModified(org.wamblee.usermgt
+ * .User)
*/
public void userModified(User aUser) {
- _users.userModified(aUser);
+ users.userModified(aUser);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#groupModified(org.wamblee.usermgt.Group)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#groupModified(org.wamblee.usermgt
+ * .Group)
*/
public void groupModified(Group aGroup) {
- _groups.groupModified(aGroup);
+ groups.groupModified(aGroup);
}
/*
* @see org.wamblee.usermgt.UserAdministration#getUser(java.lang.String)
*/
public User getUser(String aName) {
- return _users.find(aName);
+ return users.find(aName);
}
/*
* @see org.wamblee.usermgt.UserAdministration#getGroup(java.lang.String)
*/
public Group getGroup(String aName) {
- return _groups.find(aName);
+ return groups.find(aName);
}
/*
* @see org.wamblee.usermgt.UserAdministration#getUsers()
*/
public Set<User> getUsers() {
- return _users.list();
+ return users.list();
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#getUsers(org.wamblee.usermgt.Group)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#getUsers(org.wamblee.usermgt.Group
+ * )
*/
public Set<User> getUsers(Group aGroup) {
- return _users.list(aGroup);
+ return users.list(aGroup);
}
/*
* @see org.wamblee.usermgt.UserAdministration#getGroups()
*/
public Set<Group> getGroups() {
- return _groups.list();
+ return groups.list();
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#removeUser(org.wamblee.usermgt.User)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#removeUser(org.wamblee.usermgt
+ * .User)
*/
public void removeUser(User aUser) throws UserMgtException {
checkUser(aUser);
- _users.remove(aUser);
+ users.remove(aUser);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#removeGroup(org.wamblee.usermgt.Group)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#removeGroup(org.wamblee.usermgt
+ * .Group)
*/
public void removeGroup(Group aGroup) throws UserMgtException {
checkGroup(aGroup);
+
if (getUsers(aGroup).size() > 0) {
throw new UserMgtException(GROUP_STILL_OCCUPIED, aGroup);
}
- _groups.remove(aGroup);
+
+ groups.remove(aGroup);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#renameUser(org.wamblee.usermgt.User,
- * java.lang.String)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#renameUser(org.wamblee.usermgt
+ * .User, java.lang.String)
*/
public void renameUser(User aUser, String aUserName)
- throws UserMgtException {
+ throws UserMgtException {
checkUser(aUser);
+
if (aUser.getName().equals(aUserName)) {
throw new UserMgtException(TRIVIAL_RENAME, aUser);
}
- if (_users.find(aUserName) != null) {
+
+ if (users.find(aUserName) != null) {
throw new UserMgtException(DUPLICATE_USER, aUser);
}
- _userValidator.validate(aUserName);
- // we are modifying the user so we should re-insert it into the set
- // after renaming it.
- _users.remove(aUser);
+
+ userValidator.validate(aUserName);
+
aUser.setName(aUserName);
- _users.add(aUser);
+ users.userModified(aUser);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#renameGroup(org.wamblee.usermgt.Group,
- * java.lang.String)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#renameGroup(org.wamblee.usermgt
+ * .Group, java.lang.String)
*/
public void renameGroup(Group aGroup, String aGroupName)
- throws UserMgtException {
+ throws UserMgtException {
checkGroup(aGroup);
+
if (aGroup.getName().equals(aGroupName)) {
throw new UserMgtException(TRIVIAL_RENAME, aGroup);
}
- if (_groups.find(aGroupName) != null) {
+
+ if (groups.find(aGroupName) != null) {
throw new UserMgtException(DUPLICATE_GROUP, aGroup);
}
- _groupValidator.validate(aGroupName);
- // we are renaming the group so we should re-insert it into the set
- // after renaming it.
- _groups.remove(aGroup);
+
+ groupValidator.validate(aGroupName);
+
aGroup.setName(aGroupName);
- _groups.add(aGroup);
+ groups.groupModified(aGroup);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#addUserToGroup(org.wamblee.usermgt.User,
- * org.wamblee.usermgt.Group)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#addUserToGroup(org.wamblee.usermgt
+ * .User, org.wamblee.usermgt.Group)
*/
public void addUserToGroup(User aUser, Group aGroup)
- throws UserMgtException {
+ throws UserMgtException {
checkUser(aUser);
checkGroup(aGroup);
aUser.addGroup(aGroup);
- _users.userModified(aUser);
+ users.userModified(aUser);
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.usermgt.UserAdministration#removeUserFromGroup(org.wamblee.usermgt.User,
- * org.wamblee.usermgt.Group)
+ * @see
+ * org.wamblee.usermgt.UserAdministration#removeUserFromGroup(org.wamblee
+ * .usermgt.User, org.wamblee.usermgt.Group)
*/
public void removeUserFromGroup(User aUser, Group aGroup)
- throws UserMgtException {
+ throws UserMgtException {
checkUser(aUser);
checkGroup(aGroup);
aUser.removeGroup(aGroup);
- _users.userModified(aUser);
+ users.userModified(aUser);
}
/**
+ *
* @param aUser
+ *
* @throws UserMgtException
*/
private void checkUser(User aUser) throws UserMgtException {
- if (!_users.contains(aUser)) {
+ if (!users.contains(aUser)) {
throw new UserMgtException(UNKNOWN_USER, aUser);
}
}
/**
+ *
* @param aGroup
+ *
* @throws UserMgtException
*/
private void checkGroup(Group aGroup) throws UserMgtException {
- if (!_groups.contains(aGroup)) {
+ if (!groups.contains(aGroup)) {
throw new UserMgtException(UNKNOWN_GROUP, aGroup);
}
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.UserAdministration#getUserCount()
*/
public int getUserCount() {
- return _users.size();
+ return users.size();
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.UserAdministration#getGroupCount()
*/
public int getGroupCount() {
- return _groups.size();
+ return groups.size();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
import java.util.EnumMap;
/**
- * User management exception.
- *
+ * User management exception.
+ *
* @author Erik Brakkee
*/
public class UserMgtException extends Exception {
-
- static final long serialVersionUID = 5585349754997507529L;
-
- /**
- * Possible causes for the exception.
- *
- */
- public enum Reason {
- UNKNOWN_USER,
- UNKNOWN_GROUP,
- DUPLICATE_USER,
- DUPLICATE_GROUP,
- USER_ALREADY_IN_GROUP,
- USER_NOT_IN_GROUP,
- TRIVIAL_RENAME,
- INVALID_PASSWORD,
- GROUP_STILL_OCCUPIED,
- USER_MUST_BE_IN_A_GROUP,
- INVALID_USERNAME,
- INVALID_GROUPNAME
- }
-
+ static final long serialVersionUID = 5585349754997507529L;
+
/**
- * Mapping of enum to exception message text.
+ * Mapping of enum to exception message text.
*/
- private static final EnumMap<Reason,String> MESSAGES = new EnumMap<Reason,String>(Reason.class);
-
+ private static final EnumMap<Reason, String> MESSAGES = new EnumMap<Reason, String>(
+ Reason.class);
+
static {
MESSAGES.put(Reason.UNKNOWN_USER, "Unknown user");
MESSAGES.put(Reason.UNKNOWN_GROUP, "Unknown group");
MESSAGES.put(Reason.TRIVIAL_RENAME, "Trivial rename");
MESSAGES.put(Reason.INVALID_PASSWORD, "Invalid password");
MESSAGES.put(Reason.GROUP_STILL_OCCUPIED, "Group still occupied");
- MESSAGES.put(Reason.USER_MUST_BE_IN_A_GROUP, "User must be in at least one group");
+ MESSAGES.put(Reason.USER_MUST_BE_IN_A_GROUP,
+ "User must be in at least one group");
MESSAGES.put(Reason.INVALID_USERNAME, "Invalid user name");
MESSAGES.put(Reason.INVALID_GROUPNAME, "Invalid group name");
}
-
+
/**
- * Cause of the exception.
+ * Cause of the exception.
*/
- private Reason _cause;
-
+ private Reason cause;
+
/**
- * User or null if no user is relevant for the problem.
+ * User or null if no user is relevant for the problem.
*/
- private User _user;
-
+ private User user;
+
/**
- * Group or null if no group is relevant for the problem.
+ * Group or null if no group is relevant for the problem.
*/
- private Group _group;
+ private Group group;
+ /**
+ * Creates a new UserMgtException object.
+ *
+ */
public UserMgtException(Reason aCause, String aMessage) {
super(MESSAGES.get(aCause) + ": " + aMessage);
- _cause = aCause;
+ cause = aCause;
}
-
+
+ /**
+ * Creates a new UserMgtException object.
+ *
+ */
public UserMgtException(Reason aCause, User aUser) {
this(aCause, "for user '" + aUser.getName() + "'");
- _user = aUser;
+ user = aUser;
}
-
+
+ /**
+ * Creates a new UserMgtException object.
+ *
+ */
public UserMgtException(Reason aCause, Group aGroup) {
this(aCause, "for group '" + aGroup.getName() + "'");
- _group = aGroup;
+ group = aGroup;
}
-
+
+ /**
+ * Creates a new UserMgtException object.
+ *
+ */
public UserMgtException(Reason aCause, User aUser, Group aGroup) {
- this(aCause, "for user '" + aUser.getName() + "' and group '" + aGroup.getName() + "'");
- _user = aUser;
- _group = aGroup;
+ this(aCause, "for user '" + aUser.getName() + "' and group '" +
+ aGroup.getName() + "'");
+ user = aUser;
+ group = aGroup;
}
/**
- * Gets the cause of the problem.
- * @return Cause.
+ * Gets the cause of the problem.
+ *
+ * @return Cause.
*/
public Reason getReason() {
- return _cause;
+ return cause;
}
-
+
/**
- * Gets the user for which the problem occurred.
- * @return User or null if not applicable.
+ * Gets the user for which the problem occurred.
+ *
+ * @return User or null if not applicable.
*/
public User getUser() {
- return _user;
+ return user;
}
-
+
/**
- * Gets the group for which the problem occured.
- * @return Group or null if not applicable.
+ * Gets the group for which the problem occured.
+ *
+ * @return Group or null if not applicable.
*/
public Group getGroup() {
- return _group;
- }
+ return group;
+ }
+
+ /**
+ * Possible causes for the exception.
+ *
+ */
+ public enum Reason {
+ UNKNOWN_USER, UNKNOWN_GROUP, DUPLICATE_USER, DUPLICATE_GROUP, USER_ALREADY_IN_GROUP, USER_NOT_IN_GROUP, TRIVIAL_RENAME, INVALID_PASSWORD, GROUP_STILL_OCCUPIED, USER_MUST_BE_IN_A_GROUP, INVALID_USERNAME, INVALID_GROUPNAME;
+ }
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt;
+
+import java.util.Set;
+
+/**
+ * Represents a set of users. Typical implementations would be an implementation
+ * based on a static configuration file or an implementation backed by a
+ * database.
+ *
+ * @author Erik Brakkee
+ */
+public interface UserSet {
+ /**
+ * Creates a user.
+ *
+ * @param aUsername
+ * User name.
+ * @param aPassword
+ * Password.
+ * @param aGroup
+ * Group.
+ *
+ * @return New user.
+ *
+ * @throws UserMgtException
+ * In case the user cannot be created.
+ */
+ User createUser(String aUsername, String aPassword, Group aGroup)
+ throws UserMgtException;
+
+ /**
+ * Must be called whenever a user object has been modified to notify the
+ * user set.
+ *
+ * @param aUser
+ * Modified user.
+ */
+ void userModified(User aUser);
+
+ /**
+ * Finds user.
+ *
+ * @param aName
+ * Username.
+ *
+ * @return User or null if not found.
+ */
+ User find(String aName);
+
+ /**
+ * Checks if a user exists.
+ *
+ * @param aUser
+ * User.
+ *
+ * @return True iff the user exists.
+ */
+ boolean contains(User aUser);
+
+ /**
+ * Adds a user. If the user already exists, the user details are updated
+ * with that of the specified user object.
+ *
+ * @param aUser
+ * User to add.
+ *
+ */
+ boolean add(User aUser);
+
+ /**
+ * Removes a user. If the user does not exist, nothing happens.
+ *
+ * @param aUser
+ *
+ */
+ boolean remove(User aUser);
+
+ /**
+ * Lists the current users.
+ *
+ * @return Users.
+ */
+ Set<User> list();
+
+ /**
+ * Lists the users belonging to a particular group.
+ *
+ * @param aGroup
+ * Group.
+ * @return Groups.
+ */
+ Set<User> list(Group aGroup);
+
+ /**
+ *
+ * @return The number of users.
+ */
+ int size();
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt.jpa;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.wamblee.persistence.JpaMergeSupport;
+import org.wamblee.usermgt.Group;
+import org.wamblee.usermgt.GroupSet;
+
+/**
+ * Group set backed by the database.
+ *
+ * @author Erik Brakkee
+ */
+public class JpaGroupSet implements GroupSet {
+
+ private EntityManager em;
+
+ public JpaGroupSet(EntityManager aEm) {
+ em = aEm;
+ }
+
+ @Override
+ public boolean add(Group aGroup) {
+ assert aGroup.getPrimaryKey() == null;
+ if (contains(aGroup)) {
+ return false;
+ }
+ em.persist(aGroup);
+ return true;
+ }
+
+ @Override
+ public boolean contains(Group aGroup) {
+ return find(aGroup.getName()) != null;
+ }
+
+ @Override
+ public Group find(String aName) {
+ TypedQuery<Group> query = em.createNamedQuery(Group.QUERY_FIND_BY_NAME,
+ Group.class);
+ query.setParameter(Group.NAME_PARAM, aName);
+ List<Group> groups = query.getResultList();
+ if (groups.size() > 1) {
+ throw new RuntimeException(
+ "More than one group with the same name '" + aName + "'");
+ }
+
+ if (groups.size() == 0) {
+ return null;
+ }
+ return groups.get(0);
+ }
+
+ @Override
+ public void groupModified(Group aGroup) {
+ assert aGroup.getPrimaryKey() != null;
+ Group merged = em.merge(aGroup);
+ // Need to flush so that version of the merged instance is updated so we
+ // can use
+ // the updated version in the original group passed in. That allows the
+ // same
+ // group object to continue to be used as a detached object.
+ em.flush();
+ JpaMergeSupport.merge(merged, aGroup);
+ }
+
+ @Override
+ public Set<Group> list() {
+ List<Group> groups = em.createNamedQuery(Group.QUERY_ALL_GROUPS,
+ Group.class).getResultList();
+ Set<Group> res = new TreeSet<Group>(groups);
+ return res;
+ }
+
+ @Override
+ public boolean remove(Group aGroup) {
+ Group group = find(aGroup.getName());
+ if (group == null) {
+ return false;
+ }
+ em.remove(group);
+ return true;
+ }
+
+ @Override
+ public int size() {
+ Long res = (Long) em.createNamedQuery(Group.QUERY_COUNT_GROUPS)
+ .getSingleResult();
+ return res.intValue();
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package org.wamblee.usermgt.hibernate;
+package org.wamblee.usermgt.jpa;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
-import org.hibernate.SessionFactory;
-import org.springframework.orm.hibernate3.HibernateTemplate;
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+
import org.wamblee.cache.Cache;
-import org.wamblee.persistence.hibernate.HibernateSupport;
+import org.wamblee.persistence.JpaMergeSupport;
import org.wamblee.security.encryption.MessageDigester;
import org.wamblee.usermgt.AbstractUserSet;
import org.wamblee.usermgt.Group;
/**
* User set backed by the database.
- *
+ *
* @author Erik Brakkee
*/
-public class HibernateUserSet extends AbstractUserSet {
-
- private static final String QUERY_FIND_BY_NAME = "findUserByName";
-
- private static final String QUERY_FIND_BY_GROUP_NAME = "findUserByGroupName";
-
- private static final String PARAM_NAME = "name";
-
- private static final String QUERY_COUNT_USERS = "countUsers";
+public class JpaUserSet extends AbstractUserSet {
/**
- * Cache of users. Every user in the cache has its password validator and encoder set.
- */
- private Cache<String, User> _cache;
-
- /**
- * Spring hibernate support.
+ * Cache of users. Every user in the cache has its password validator and
+ * encoder set.
*/
- private HibernateSupport _hibernateSupport;
+ private Cache<String, User> cache;
+
+ private EntityManager entityManager;
/**
* Constructs a user set backed by the database.
- * @param aCache User cache to use.
+ *
+ * @param aCache
+ * User cache to use.
*/
- public HibernateUserSet(Cache<String,User> aCache,
- NameValidator aPasswordValidator, MessageDigester aPasswordEncoder) {
+ public JpaUserSet(Cache<String, User> aCache,
+ NameValidator aPasswordValidator, MessageDigester aPasswordEncoder,
+ EntityManager aEntityManager) {
super(aPasswordValidator, aPasswordEncoder);
- _cache = aCache;
- _hibernateSupport = new HibernateSupport();
+ cache = aCache;
+ entityManager = aEntityManager;
}
-
- /**
- * Sets the session factory.
- * @param aFactory Session factory.
- */
- public void setSessionFactory(SessionFactory aFactory) {
- _hibernateSupport.setSessionFactory(aFactory);
- }
-
- /**
- * Gets the hibernate template.
- * @return Hibernate template.
- */
- private HibernateTemplate getHibernateTemplate() {
- return _hibernateSupport.getHibernateTemplate();
- }
-
+
/*
* (non-Javadoc)
*
*/
public void userModified(User aUser) {
assert aUser.getPrimaryKey() != null;
- _hibernateSupport.merge(aUser);
- _cache.remove(aUser.getName());
+ User merged = entityManager.merge(aUser);
+ // Need to flush the entity manager to make sure the version is updated.
+ entityManager.flush();
+ JpaMergeSupport.merge(merged, aUser);
+ cache.remove(aUser.getName());
setPasswordInfo(aUser);
- _cache.put(aUser.getName(), new User(aUser));
+ cache.put(aUser.getName(), new User(aUser));
}
/*
* @see org.wamblee.usermgt.UserSet#find(java.lang.String)
*/
public User find(String aName) {
- User user = _cache.get(aName);
+ User user = cache.get(aName);
+
if (user != null) {
return user;
}
- List result = getHibernateTemplate().findByNamedQueryAndNamedParam(
- QUERY_FIND_BY_NAME, PARAM_NAME, aName);
- if (result.size() > 1) {
- throw new RuntimeException(
- "Implementation problem, more than one user with the same name!");
- }
- if (result.size() == 0) {
+
+ TypedQuery<User> query = entityManager.createNamedQuery(
+ User.QUERY_FIND_BY_NAME, User.class);
+ query.setParameter(User.NAME_PARAM, aName);
+ try {
+ user = query.getSingleResult();
+ user = new User(user);
+ setPasswordInfo(user);
+ cache.put(aName, user);
+ return user;
+ } catch (NoResultException e) {
return null;
}
- user = (User) result.get(0);
- setPasswordInfo(user);
- _cache.put(aName, user);
- return new User(user);
}
/*
*/
public boolean add(User aUser) {
assert aUser.getPrimaryKey() == null;
+
if (contains(aUser)) {
return false;
}
- getHibernateTemplate().saveOrUpdate(aUser);
+
+ entityManager.persist(aUser);
setPasswordInfo(aUser);
- _cache.put(aUser.getName(), aUser);
+ cache.put(aUser.getName(), aUser);
+
return true;
}
* @see org.wamblee.usermgt.UserSet#remove(org.wamblee.usermgt.User)
*/
public boolean remove(User aUser) {
- assert aUser.getPrimaryKey() != null;
if (!contains(aUser)) {
return false;
}
- User user = (User) getHibernateTemplate().merge(aUser);
- getHibernateTemplate().delete(user);
- aUser.setPersistedVersion(-1);
- aUser.setPrimaryKey(null);
- _cache.remove(aUser.getName());
+
+ User user = entityManager.merge(aUser);
+ entityManager.remove(user);
+ cache.remove(aUser.getName());
+
return true;
}
*/
public Set<User> list() {
Set<User> users = new TreeSet<User>();
- List<User> list = getHibernateTemplate().loadAll(User.class);
+ List<User> list = entityManager.createNamedQuery(User.QUERY_ALL_USERS,
+ User.class).getResultList();
+
for (User user : list) {
setPasswordInfo(user);
users.add(new User(user));
}
+
return users;
}
*/
public Set<User> list(Group aGroup) {
Set<User> users = new TreeSet<User>();
- List<User> list = getHibernateTemplate().findByNamedQueryAndNamedParam(
- QUERY_FIND_BY_GROUP_NAME, PARAM_NAME, aGroup.getName());
+ TypedQuery<User> query = entityManager.createNamedQuery(
+ User.QUERY_FIND_BY_GROUP_NAME, User.class);
+ query.setParameter(User.NAME_PARAM, aGroup.getName());
+
+ List<User> list = query.getResultList();
+
for (User user : list) {
setPasswordInfo(user);
users.add(new User(user));
}
+
return users;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.usermgt.UserSet#size()
*/
public int size() {
- Long result = (Long)getHibernateTemplate().findByNamedQuery(QUERY_COUNT_USERS).get(0);
- return result.intValue();
+ Long result = entityManager.createNamedQuery(User.QUERY_COUNT_USERS, Long.class).getSingleResult();
+ return result.intValue();
}
}
<hibernate-mapping>
- <class name="org.wamblee.security.authorization.AuthorizationRule"
+ <class name="org.wamblee.security.authorization.AbstractAuthorizationRule"
table="AUTHORIZATION_RULES"
select-before-update="true"
lazy="false">
<property name="authorizationResultString" column="RESULT"/>
<property name="resourceClassName" column="RESOURCE_CLASSNAME"/>
<many-to-one name="userCondition"
- class="org.wamblee.security.authorization.UserCondition"
+ class="org.wamblee.security.authorization.AbstractUserCondition"
column="USERCONDITION_ID"
cascade="all"
lazy="false"/>
<many-to-one name="pathCondition"
- class="org.wamblee.security.authorization.PathCondition"
+ class="org.wamblee.security.authorization.AbstractPathCondition"
column="PATHCONDITION_ID"
cascade="all"
lazy="false"/>
<many-to-one name="operationCondition"
- class="org.wamblee.security.authorization.OperationCondition"
+ class="org.wamblee.security.authorization.AbstractOperationCondition"
column="OPERATIONCONDITION_ID"
cascade="all"
lazy="false"/>
<hibernate-mapping>
- <class name="org.wamblee.security.authorization.AuthorizationService" table="AUTHORIZATION_SERVICE"
+ <class name="org.wamblee.security.authorization.AbstractAuthorizationService" table="AUTHORIZATION_SERVICE"
select-before-update="true">
<id name="primaryKey" column="ID" type="long">
<generator class="native"/>
<list name="mappedRules" table="AUTHORIZATION_SERVICE_RULES" lazy="false" cascade="all-delete-orphan">
<key column="ID"/>
<index column="POSITION"/>
- <many-to-many class="org.wamblee.security.authorization.AuthorizationRule"
+ <many-to-many class="org.wamblee.security.authorization.AbstractAuthorizationRule"
column="RULE_ID"/>
</list>
</subclass>
<query name="findAuthorizationServiceByName">
select service
- from org.wamblee.security.authorization.AuthorizationService service
+ from org.wamblee.security.authorization.AbstractAuthorizationService service
where service.name = :name
</query>
<hibernate-mapping>
- <class name="org.wamblee.security.authorization.OperationCondition" table="OPERATION_CONDITIONS"
+ <class name="org.wamblee.security.authorization.AbstractOperationCondition" table="OPERATION_CONDITIONS"
select-before-update="true"
lazy="false">
<id name="primaryKey" column="ID" type="long">
<hibernate-mapping>
- <class name="org.wamblee.security.authorization.PathCondition" table="PATH_CONDITIONS"
+ <class name="org.wamblee.security.authorization.AbstractPathCondition" table="PATH_CONDITIONS"
select-before-update="true"
lazy="false">
<id name="primaryKey" column="ID" type="long">
<hibernate-mapping>
- <class name="org.wamblee.security.authorization.PathCondition" table="PATH_CONDITIONS"
+ <class name="org.wamblee.security.authorization.AbstractPathCondition" table="PATH_CONDITIONS"
select-before-update="true"
lazy="false">
<id name="primaryKey" column="ID" type="long">
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
+
<class name="org.wamblee.usermgt.User" table="USERS" select-before-update="true">
<id name="primaryKey" column="ID" type="long">
<hibernate-mapping>
- <class name="org.wamblee.security.authorization.UserCondition" table="USER_CONDITIONS"
+ <class name="org.wamblee.security.authorization.AbstractUserCondition" table="USER_CONDITIONS"
select-before-update="true"
lazy="false">
<id name="primaryKey" column="ID" type="long">
</constructor-arg>
</bean>
- <bean id="org.wamblee.security.authorization.AuthorizationService"
+ <bean id="org.wamblee.security.authorization.AbstractAuthorizationService"
class="org.wamblee.security.authorization.hibernate.PersistentAuthorizationService">
<constructor-arg><value>DEFAULT</value></constructor-arg>
<constructor-arg><ref bean="org.springframework.orm.hibernate3.HibernateTemplate"/></constructor-arg>
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import junit.framework.TestCase;
+import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
+import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
+
+import org.wamblee.usermgt.UserAccessor;
+
+/**
+ * Tests the authorization service.
+ *
+ * @author Erik Brakkee
+ */
+public class AuthorizationServiceTest extends TestCase {
+ private AbstractAuthorizationRule rule1;
+
+ private AbstractAuthorizationRule rule2;
+
+ private AbstractAuthorizationRule rule3;
+
+ private AuthorizationService service;
+
+ protected AuthorizationService getService() {
+ return service;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ rule1 = createRule(GRANTED, "users", "/oni/", AllOperation.class);
+ rule2 = createRule(DENIED, "users", "/abc/", ReadOperation.class);
+ rule3 = createRule(GRANTED, "users", "/abc/", AllOperation.class);
+
+ service = createService();
+ service.appendRule(rule1);
+ service.appendRule(rule2);
+ service.appendRule(rule3);
+ }
+
+ protected void resetTestRules() {
+ ((TestAuthorizationRule) rule1).reset();
+ ((TestAuthorizationRule) rule2).reset();
+ ((TestAuthorizationRule) rule3).reset();
+ }
+
+ protected UserAccessor createUserAccessor() {
+ return new TestUserAccessor();
+ }
+
+ /**
+ * Creates an authorization service with some rules for testing. .
+ *
+ * @return Authorization service.
+ */
+ protected AuthorizationService createService() {
+ DefaultAuthorizationService service = new DefaultAuthorizationService();
+ service.setUserAccessor(createUserAccessor());
+
+ return service;
+ }
+
+ protected AbstractAuthorizationRule createRule(AuthorizationResult aResult,
+ String aGroup, String aPath, Class<? extends Operation> aOperation) {
+ return new TestAuthorizationRule(aResult, aGroup, aPath, aOperation);
+ }
+
+ protected void checkMatchCount(int aCount, AuthorizationRule aRule) {
+ TestAuthorizationRule testRule = (TestAuthorizationRule) aRule;
+ assertEquals(aCount, testRule.getMatchCount());
+ testRule.reset();
+ }
+
+ protected Object createResource(String aPath) {
+ return new TestResource(aPath);
+ }
+
+ protected void checkRuleCount(int aCount) {
+ // Empty
+ }
+
+ /**
+ * Several checks to verify the outcome of matching against the first rule.
+ */
+ public void testFirstRuleGrants() {
+ assertTrue(service.isAllowed(createResource("/oni/xyz.jpg"),
+ new ReadOperation()));
+ checkMatchCount(1, service.getRules()[0]);
+ assertTrue(service.isAllowed(createResource("/oni/xyz.jpg"),
+ new WriteOperation()));
+ checkMatchCount(1, service.getRules()[0]);
+ assertTrue(service.isAllowed(createResource("/oni/xyz.jpg"),
+ new DeleteOperation()));
+ checkMatchCount(1, service.getRules()[0]);
+ assertTrue(service.isAllowed(createResource("/oni/xyz.jpg"),
+ new CreateOperation()));
+ checkMatchCount(1, service.getRules()[0]);
+ checkMatchCount(0, service.getRules()[1]);
+ checkMatchCount(0, service.getRules()[2]);
+ }
+
+ /**
+ * Verify that a match with the second rule leads to a denial of
+ * authorization.
+ */
+ public void testSecondRuleDenies() {
+ assertFalse(service.isAllowed(createResource("/abc/xyz.jpg"),
+ new ReadOperation()));
+ checkMatchCount(0, service.getRules()[0]);
+ checkMatchCount(1, service.getRules()[1]);
+ checkMatchCount(0, service.getRules()[2]);
+ }
+
+ /**
+ * Verifies that the third rule is used when appropriate and that it grants
+ * access.
+ */
+ public void testThirdRuleGrants() {
+ assertTrue(service.isAllowed(createResource("/abc/xyz.jpg"),
+ new WriteOperation()));
+ checkMatchCount(0, service.getRules()[0]);
+ checkMatchCount(0, service.getRules()[1]);
+ checkMatchCount(1, service.getRules()[2]);
+ }
+
+ /**
+ * Removes a rule and checks it is removed.
+ */
+ public void testRemoveRule() {
+ checkRuleCount(3);
+ assertTrue(service.isAllowed(createResource("/abc/xyz.jpg"),
+ new WriteOperation()));
+ service.removeRule(2);
+ assertFalse(service.isAllowed(createResource("/abc/xyz.jpg"),
+ new WriteOperation()));
+ checkRuleCount(2);
+ }
+
+ /**
+ * Inserts a rule and checks it is inserted.
+ */
+ public void testInsertRule() {
+ checkRuleCount(3);
+ assertFalse(service.isAllowed(createResource("/janse/xyz.jpg"),
+ new WriteOperation()));
+ service.appendRule(createRule(GRANTED, "users", "/janse/",
+ WriteOperation.class));
+ assertTrue(service.isAllowed(createResource("/janse/xyz.jpg"),
+ new WriteOperation()));
+ checkRuleCount(4);
+ }
+
+ /**
+ * Gets the rules. Verifies that all rules are obtained.
+ */
+ public void testGetRules() {
+ AuthorizationRule[] rules = service.getRules();
+ assertEquals(3, rules.length);
+ }
+
+ /**
+ * Verifies that when no rules match, access is denied.
+ */
+ public void testNoRulesSupportResource() {
+ assertFalse(service.isAllowed(createResource("/xyxyxyxy"),
+ new ReadOperation()));
+ checkMatchCount(0, service.getRules()[0]);
+ checkMatchCount(0, service.getRules()[1]);
+ checkMatchCount(0, service.getRules()[2]);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import junit.framework.TestCase;
+
+/**
+ * Test of the operation registry.
+ *
+ * @author Erik Brakkee
+ */
+public class DefaultOperationRegistryTest extends TestCase {
+ private OperationRegistry registry;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ registry = new DefaultOperationRegistry(new Operation[] {
+ new AllOperation(), new ReadOperation(), new WriteOperation(),
+ new DeleteOperation(), new CreateOperation() });
+ }
+
+ /**
+ * Tests encoding and decoding of no operations.
+ */
+ public void testEncodeDecodeNooperations() {
+ assertEquals("", registry.encode(new Operation[0]));
+ assertEquals(0, registry.decode(Object.class, "").length);
+ }
+
+ /**
+ * Verifies that encoding of operations into a string works.
+ */
+ public void testEncode() {
+ assertEquals("read,write", registry.encode(new Operation[] {
+ new ReadOperation(), new WriteOperation() }));
+ }
+
+ /**
+ * Verifies that decoding of operation from a string works.
+ */
+ public void testDecode() {
+ Operation[] operations = registry.decode(Object.class, "read,write");
+ assertTrue(operations[0] instanceof ReadOperation);
+ assertTrue(operations[1] instanceof WriteOperation);
+ }
+
+ /**
+ * Verifies that an IllegalArgumentException occurs when attempting to
+ * decode an operation that is not known.
+ */
+ public void testDecodeUnknownOperation() {
+ try {
+ registry.decode(Object.class, "bla");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // ok
+ }
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
import junit.framework.TestCase;
/**
- * Test for regular expression matching.
- *
+ * Test for regular expression matching.
+ *
* @author Erik Brakkee
*/
public class RegexpPathConditionTest extends TestCase {
-
/**
- * Various tests.
- *
+ * Various tests.
*/
- public void testMatch() {
- PathCondition cond = new RegexpPathCondition("abc");
- assertTrue(cond.matches("abc"));
- assertFalse(cond.matches("xabcx"));
- cond = new RegexpPathCondition("/[a-z]*/.*");
- assertTrue(cond.matches("/hallo/xyz"));
+ public void testMatch() {
+ PathCondition cond = new RegexpPathCondition("abc");
+ assertTrue(cond.matches("abc"));
+ assertFalse(cond.matches("xabcx"));
+ cond = new RegexpPathCondition("/[a-z]*/.*");
+ assertTrue(cond.matches("/hallo/xyz"));
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
import junit.framework.TestCase;
/**
- * Tests for StartsWithPathCondition.
- *
+ * Tests for StartsWithPathCondition.
+ *
* @author Erik Brakkee
*/
public class StartsWithPathConditionTest extends TestCase {
-
/**
- * Various tests.
+ * Various tests.
*/
public void testMatches() {
PathCondition cond = new StartsWithPathCondition("/hallo");
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization;
+
+import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
+import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.Transient;
+
+import org.wamblee.usermgt.User;
+
+/**
+ * Test authorization rule that also counts the number of times the rule
+ * matches.
+ *
+ * @author Erik Brakkee
+ */
+@Entity
+@DiscriminatorValue("TEST")
+public class TestAuthorizationRule extends UrlAuthorizationRule {
+ /**
+ * Counts the number of matches.
+ */
+ @Transient
+ private int matches = 0;
+
+ /**
+ * Creates a new TestAuthorizationRule object.
+ *
+ */
+ public TestAuthorizationRule(AuthorizationResult aResult, String aGroup,
+ String aPath, Class<? extends Operation> aOperation) {
+ super(aResult, new GroupUserCondition(aGroup),
+ new StartsWithPathCondition(aPath), TestResource.class,
+ new IsaOperationCondition(aOperation));
+ }
+
+ /**
+ * Creates a new TestAuthorizationRule object.
+ */
+ protected TestAuthorizationRule() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.UrlAuthorizationRule#getPath(java.
+ * lang.Object)
+ */
+ @Override
+ protected String getResourcePath(Object aResource) {
+ return ((TestResource) aResource).getPath();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.UrlAuthorizationRule#isAllowed(java
+ * .lang.Object, org.wamblee.security.authorization.Operation,
+ * org.wamblee.usermgt.UserAccessor)
+ */
+ @Override
+ public AuthorizationResult isAllowed(Object aResource,
+ Operation aOperation, User aUser) {
+ AuthorizationResult result = super.isAllowed(aResource, aOperation,
+ aUser);
+
+ if (result.equals(GRANTED) || result.equals(DENIED)) {
+ matches++;
+ }
+
+ return result;
+ }
+
+ public int getMatchCount() {
+ return matches;
+ }
+
+ public void reset() {
+ matches = 0;
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
/**
- * A test resource for authorization.
- *
+ * A test resource for authorization.
+ *
* @author Erik Brakkee
*/
public class TestResource {
+ private String path;
- private String _path;
-
- public TestResource(String aPath) {
- _path = aPath;
+ /**
+ * Creates a new TestResource object.
+ *
+ */
+ public TestResource(String aPath) {
+ path = aPath;
}
-
- public String getPath() {
- return _path;
+
+ public String getPath() {
+ return path;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.security.authorization;
import junit.framework.TestCase;
import org.wamblee.security.encryption.Md5HexMessageDigester;
+
import org.wamblee.usermgt.Group;
import org.wamblee.usermgt.InMemoryGroupSet;
import org.wamblee.usermgt.InMemoryUserSet;
import org.wamblee.usermgt.UserMgtException.Reason;
/**
- * User access that always returns a user that belongs to
- * a fixed group.
- *
+ * User access that always returns a user that belongs to a fixed group.
+ *
* @author Erik Brakkee
*/
public class TestUserAccessor implements UserAccessor {
-
- private static final String USER = "erik";
+ private static final String USER = "erik";
+
private static final String PASSWORD = "abc123";
+
private static final String GROUP = "users";
/*
*/
public User getCurrentUser() {
UserAdministration admin = new UserAdministrationImpl(
- new InMemoryUserSet( new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"),
- new Md5HexMessageDigester()), new InMemoryGroupSet(),
- new RegexpNameValidator(RegexpNameValidator.ID_PATTERN, Reason.INVALID_USERNAME, "Invalid user"),
- new RegexpNameValidator(RegexpNameValidator.ID_PATTERN, Reason.INVALID_GROUPNAME, "Invalid group")
- );
+ new InMemoryUserSet(new RegexpNameValidator(
+ RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD,
+ "Password must contain at least 6 characters"),
+ new Md5HexMessageDigester()), new InMemoryGroupSet(),
+ new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
+ Reason.INVALID_USERNAME, "Invalid user"),
+ new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
+ Reason.INVALID_GROUPNAME, "Invalid group"));
+
try {
Group group = admin.createGroup(GROUP);
+
return admin.createUser(USER, PASSWORD, group);
} catch (UserMgtException e) {
TestCase.fail(e.getMessage());
throw new RuntimeException(e);
}
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.authorization;
+import junit.framework.TestCase;
import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
import static org.wamblee.security.authorization.AuthorizationResult.UNDECIDED;
import static org.wamblee.security.authorization.AuthorizationResult.UNSUPPORTED_RESOURCE;
-import junit.framework.TestCase;
import org.wamblee.usermgt.User;
-
/**
- * Tests for the {@link org.wamblee.security.authorization.UrlAuthorizationRule}.
- *
+ * Tests for the {@link org.wamblee.security.authorization.UrlAuthorizationRule}
+ * .
+ *
* @author Erik Brakkee
*/
public class UrlAuthorizationRuleTest extends TestCase {
-
/**
- * Constructs the rule with a result of UNDECIDED. Verifies that an IllegalArgumentException
- * is thrown.
- *
+ * Constructs the rule with a result of UNDECIDED. Verifies that an
+ * IllegalArgumentException is thrown.
*/
- public void testConstructWithUndecidedResult() {
- try {
- new TestAuthorizationRule(UNDECIDED, "users", "/path", ReadOperation.class);
+ public void testConstructWithUndecidedResult() {
+ try {
+ new TestAuthorizationRule(UNDECIDED, "users", "/path",
+ ReadOperation.class);
fail();
- } catch (IllegalArgumentException e) {
- // ok
+ } catch (IllegalArgumentException e) {
+ // ok
}
}
-
+
/**
- * Constructs the rule with a result of UNSUPPORTED_RESOURCE. Verifies that an IllegalArgumentException
- * is thrown.
- *
+ * Constructs the rule with a result of UNSUPPORTED_RESOURCE. Verifies that
+ * an IllegalArgumentException is thrown.
*/
- public void testConstructWithUnsupportedResult() {
- try {
- new TestAuthorizationRule(UNSUPPORTED_RESOURCE, "users", "/path", ReadOperation.class);
+ public void testConstructWithUnsupportedResult() {
+ try {
+ new TestAuthorizationRule(UNSUPPORTED_RESOURCE, "users", "/path",
+ ReadOperation.class);
fail();
- } catch (IllegalArgumentException e) {
- // ok
+ } catch (IllegalArgumentException e) {
+ // ok
}
}
-
+
/**
- * Constructs the authorization rule and applies it to an unsupported object type.
- * Verifies that the result is UNSUPPORTED_RESOURCE.
- *
+ * Constructs the authorization rule and applies it to an unsupported object
+ * type. Verifies that the result is UNSUPPORTED_RESOURCE.
*/
- public void testUnsupportedObject() {
- AuthorizationRule rule = new TestAuthorizationRule(GRANTED, "users", "/path", ReadOperation.class);
- assertEquals(UNSUPPORTED_RESOURCE, rule.isAllowed("hello", new ReadOperation(), new TestUserAccessor().getCurrentUser()));
+ public void testUnsupportedObject() {
+ AuthorizationRule rule = new TestAuthorizationRule(GRANTED, "users",
+ "/path", ReadOperation.class);
+ assertEquals(UNSUPPORTED_RESOURCE, rule.isAllowed("hello",
+ new ReadOperation(), new TestUserAccessor().getCurrentUser()));
}
-
- public void testMatchingScenarios() {
- AuthorizationRule rule = new TestAuthorizationRule(GRANTED, "users", "/path/", ReadOperation.class);
+
+ public void testMatchingScenarios() {
+ AuthorizationRule rule = new TestAuthorizationRule(GRANTED, "users",
+ "/path/", ReadOperation.class);
User user = new TestUserAccessor().getCurrentUser();
-
+
// everything matches
- assertEquals(GRANTED, rule.isAllowed(new TestResource("/path/a"), new ReadOperation(), user));
- assertEquals(GRANTED, rule.isAllowed(new TestResource("/path/"), new ReadOperation(), user));
-
- // path does not match.
- assertEquals(UNDECIDED, rule.isAllowed(new TestResource("/path"), new ReadOperation(), user));
-
- // operation does not match.
- assertEquals(UNDECIDED, rule.isAllowed(new TestResource("/path/"), new WriteOperation(), user));
-
- // group does not match.
- AuthorizationRule rule2 = new TestAuthorizationRule(GRANTED, "users2", "/path/", ReadOperation.class);
- assertEquals(UNDECIDED, rule2.isAllowed(new TestResource("/path/a"), new ReadOperation(), user));
+ assertEquals(GRANTED, rule.isAllowed(new TestResource("/path/a"),
+ new ReadOperation(), user));
+ assertEquals(GRANTED, rule.isAllowed(new TestResource("/path/"),
+ new ReadOperation(), user));
+
+ // path does not match.
+ assertEquals(UNDECIDED, rule.isAllowed(new TestResource("/path"),
+ new ReadOperation(), user));
+
+ // operation does not match.
+ assertEquals(UNDECIDED, rule.isAllowed(new TestResource("/path/"),
+ new WriteOperation(), user));
+
+ // group does not match.
+ AuthorizationRule rule2 = new TestAuthorizationRule(GRANTED, "users2",
+ "/path/", ReadOperation.class);
+ assertEquals(UNDECIDED, rule2.isAllowed(new TestResource("/path/a"),
+ new ReadOperation(), user));
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.security.encryption;
import junit.framework.TestCase;
/**
- * Tests for the message digester.
- *
+ * Tests for the message digester.
+ *
* @author Erik Brakkee
*/
public class MessageDigesterTest extends TestCase {
-
- public void testMd5HexEncoding() {
- assertEquals("e99a18c428cb38d5f260853678922e03", new Md5HexMessageDigester().hash("abc123"));
+ public void testMd5HexEncoding() {
+ assertEquals("e99a18c428cb38d5f260853678922e03",
+ new Md5HexMessageDigester().hash("abc123"));
}
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt;
+
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the inmemory group set. Intended to be subclassed for other
+ * implementations of group set.
+ */
+public class InMemoryGroupSetTest extends TestCase {
+ private GroupSet groups;
+
+ /**
+ * This method must be overriden in subclasses.
+ *
+ * @return New group set object.
+ */
+ protected GroupSet createGroupSet() {
+ return new InMemoryGroupSet();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.test.SpringTestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ groups = createGroupSet();
+ checkGroupCount(0);
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aGroup
+ * Group to check for existence.
+ *
+ */
+ protected void checkGroupExists(String aGroup) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aGroup
+ * Group to check for non-existence.
+ *
+ */
+ protected void checkGroupNotExists(String aGroup) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aSize
+ * Expected number of groups.
+ *
+ */
+ protected void checkGroupCount(int aSize) throws Exception {
+ assertEquals(aSize, groups.size());
+ }
+
+ /**
+ * Adds a group and verifies that the group is added using find(), list(),
+ * and contains().
+ *
+ */
+ public void testAdd() throws Exception {
+ Group group = new Group("group1");
+ assertTrue(groups.add(group));
+ checkGroupExists(group.getName());
+ checkGroupCount(1);
+
+ Group group2 = groups.find("group1");
+ assertNotNull(group2);
+ assertEquals(group.getName(), group2.getName());
+
+ Set<Group> set = groups.list();
+ assertEquals(1, set.size());
+ assertTrue(set.contains(group));
+ }
+
+ /**
+ * Tries to find a non-existing group. Verifies that null is returned.
+ *
+ */
+ public void testFindUnknownGroup() throws Exception {
+ Group group1 = new Group("group1");
+ Group group2 = new Group("group2");
+ groups.add(group1);
+ groups.add(group2);
+ checkGroupExists(group1.getName());
+ checkGroupExists(group2.getName());
+
+ assertNull(groups.find("group3"));
+ checkGroupNotExists("group3");
+ }
+
+ /**
+ * Adds duplicate group. Verifies that the existing group is left untouched.
+ *
+ */
+ public void testAddDuplicateGroup() throws Exception {
+ Group group1 = new Group("group1");
+ groups.add(group1);
+
+ assertEquals(1, groups.list().size());
+ assertTrue(groups.contains(group1));
+ group1 = new Group("group1");
+ assertFalse(groups.add(group1));
+ assertEquals(1, groups.list().size());
+
+ checkGroupExists(group1.getName());
+ checkGroupCount(1);
+ }
+
+ /**
+ * Removes a group. Verifies that the group is removed and the return value
+ * is true.
+ *
+ */
+ public void testRemoveGroup() throws Exception {
+ Group group1 = new Group("group1");
+ groups.add(group1);
+ assertTrue(groups.contains(group1));
+ checkGroupCount(1);
+
+ assertTrue(groups.remove(group1));
+ assertFalse(groups.contains(group1));
+ assertNull(groups.find(group1.getName()));
+ assertEquals(0, groups.list().size());
+ checkGroupCount(0);
+ }
+
+ /**
+ * Removes a non-existing group. Verifies that no groups are removed an that
+ * the return value is true.
+ *
+ */
+ public void testRemoveNonExistingGroup() throws Exception {
+ Group group1 = new Group("group1");
+ groups.add(group1);
+ checkGroupCount(1);
+
+ Group nonExistingGroup = new Group("group2");
+ assertFalse(groups.remove(nonExistingGroup));
+ assertTrue(groups.contains(group1));
+ assertEquals(1, groups.list().size());
+ checkGroupCount(1);
+ }
+
+ /**
+ * Adds a number of groups to the set and verifies that list() returns them
+ * all.
+ *
+ */
+ public void testList() throws Exception {
+ Group group1 = new Group("group1");
+ Group group2 = new Group("group2");
+ Group group3 = new Group("group3");
+ assertTrue(groups.add(group1));
+ assertTrue(groups.add(group2));
+ assertTrue(groups.add(group3));
+
+ checkGroupExists(group1.getName());
+ checkGroupExists(group2.getName());
+ checkGroupExists(group3.getName());
+
+ Set<Group> set = groups.list();
+ assertTrue(set.contains(group1));
+ assertTrue(set.contains(group2));
+ assertTrue(set.contains(group3));
+
+ checkGroupCount(3);
+ }
+
+ public void testRenameGroupTwice() {
+ Group group = new Group("x");
+ groups.add(group);
+ groups.groupModified(group);
+ group.setName("y");
+ groups.groupModified(group);
+ Group g = groups.find("y");
+ assertNotNull(g);
+ groups.groupModified(group);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt;
+
+import junit.framework.TestCase;
+
+import org.wamblee.security.encryption.Md5HexMessageDigester;
+
+import org.wamblee.usermgt.UserMgtException.Reason;
+
+import java.sql.SQLException;
+
+import java.util.Set;
+
+/**
+ * Tests the inmemory user set. Intended to be subclassed for other
+ * implementations of user set.
+ */
+public class InMemoryUserSetTest extends TestCase {
+ protected static final String PASSWORD = "abc123";
+
+ private UserSet users;
+
+ private GroupSet groups;
+
+ private Group group;
+
+ /**
+ * This method must be overriden in subclasses.
+ *
+ * @return New user set object.
+ */
+ protected UserSet createUserSet() {
+ return new InMemoryUserSet(new RegexpNameValidator(
+ RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD,
+ "Password must contain at least 6 characters"),
+ new Md5HexMessageDigester());
+ }
+
+ /**
+ * This method must be overriden in subclasses.
+ *
+ * @return New group set object.
+ */
+ protected GroupSet createGroupSet() {
+ return new InMemoryGroupSet();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.test.SpringTestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ users = createUserSet();
+ groups = createGroupSet();
+ group = new Group("group0");
+ groups.add(group);
+ checkUserCount(0);
+ }
+
+ protected UserSet getUsers() {
+ return users;
+ }
+
+ protected GroupSet getGroups() {
+ return groups;
+ }
+
+ protected Group createGroup(String aName) {
+ return new Group(aName);
+ }
+
+ protected User createUser(String aName, String aPassword, Group aGroup)
+ throws UserMgtException {
+ return UsermgtTestUtils.createUser(aName, aPassword, aGroup);
+ }
+
+ protected void addUserToGroup(User aUser, Group aGroup)
+ throws UserMgtException {
+ aUser.addGroup(aGroup);
+ }
+
+ protected void removeUserFromGroup(User aUser, Group aGroup)
+ throws UserMgtException {
+ aUser.removeGroup(aGroup);
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aUser
+ * User to check for existence.
+ *
+ */
+ protected void checkUserExists(String aUser) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aUser
+ * User to check for non-existence.
+ *
+ */
+ protected void checkUserNotExists(String aUser) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aSize
+ * Expected number of users.
+ *
+ */
+ protected void checkUserCount(int aSize) throws Exception {
+ assertEquals(aSize, users.size());
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aUser
+ * User to check for existence.
+ *
+ */
+ protected void checkGroupExists(String aUser) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aUser
+ * User to check for non-existence.
+ *
+ */
+ protected void checkGroupNotExists(String aUser) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Additional check to be implemented by a subclass.
+ *
+ * @param aSize
+ * Expected number of users.
+ *
+ */
+ protected void checkGroupCount(int aSize) throws Exception {
+ // Empty
+ }
+
+ /**
+ * Adds a user and verifies that the user is added using find(), list(), and
+ * contains().
+ *
+ */
+ public void testAdd() throws Exception {
+ User user = createUser("user1", PASSWORD, group);
+ assertTrue(users.add(user));
+ checkUserExists(user.getName());
+ checkUserCount(1);
+
+ User user2 = users.find("user1");
+ assertNotNull(user2);
+ assertEquals(user.getName(), user2.getName());
+
+ Set<User> set = users.list();
+ assertEquals(1, set.size());
+ assertTrue(set.contains(user));
+ }
+
+ /**
+ * Tries to find a non-existing user. Verifies that null is returned.
+ *
+ */
+ public void testFindUnknownUser() throws Exception {
+ User user1 = createUser("user1", PASSWORD, group);
+ User user2 = createUser("user2", PASSWORD, group);
+ users.add(user1);
+ users.add(user2);
+ checkUserExists(user1.getName());
+ checkUserExists(user2.getName());
+
+ assertNull(users.find("user3"));
+ checkUserNotExists("user3");
+ }
+
+ /**
+ * Adds duplicate user. Verifies that the existing user is left untouched.
+ *
+ */
+ public void testAddDuplicateUser() throws Exception {
+ User user1 = createUser("user1", PASSWORD, group);
+ users.add(user1);
+
+ assertEquals(1, users.list().size());
+ assertTrue(users.contains(user1));
+ user1 = createUser("user1", PASSWORD, group);
+ assertFalse(users.add(user1));
+ assertEquals(1, users.list().size());
+
+ checkUserExists(user1.getName());
+ checkUserCount(1);
+ }
+
+ /**
+ * Removes a user. Verifies that the user is removed and the return value is
+ * true.
+ *
+ */
+ public void testRemoveUser() throws Exception {
+ User user1 = createUser("user1", PASSWORD, group);
+ users.add(user1);
+ assertTrue(users.contains(user1));
+ checkUserCount(1);
+
+ assertTrue(users.remove(user1));
+ assertFalse(users.contains(user1));
+ assertNull(users.find(user1.getName()));
+ assertEquals(0, users.list().size());
+ checkUserCount(0);
+ }
+
+ /**
+ * Removes a non-existing user. Verifies that no users are removed an that
+ * the return value is true.
+ *
+ */
+ public void testRemoveNonExistingUser() throws Exception,
+ UserMgtException {
+ User user1 = createUser("user1", PASSWORD, group);
+ users.add(user1);
+ checkUserCount(1);
+
+ User nonExistingUser = createUser("user2", PASSWORD, group);
+ assertFalse(users.remove(nonExistingUser));
+ assertTrue(users.contains(user1));
+ assertEquals(1, users.list().size());
+ checkUserCount(1);
+ }
+
+ /**
+ * Adds a number of users to the set and verifies that list() returns them
+ * all.
+ *
+ */
+ public void testList() throws Exception {
+ User user1 = createUser("user1", PASSWORD, group);
+ User user2 = createUser("user2", PASSWORD, group);
+ User user3 = createUser("user3", PASSWORD, group);
+ assertTrue(users.add(user1));
+ assertTrue(users.add(user2));
+ assertTrue(users.add(user3));
+
+ checkUserExists(user1.getName());
+ checkUserExists(user2.getName());
+ checkUserExists(user3.getName());
+
+ Set<User> set = users.list();
+ assertTrue(set.contains(user1));
+ assertTrue(set.contains(user2));
+ assertTrue(set.contains(user3));
+
+ checkUserCount(3);
+ }
+
+ /**
+ * Adds several users to different groups and verifies that the correct
+ * users are returned when looking for users in different groups.
+ *
+ * @throws SQLException
+ */
+ public void testListByGroup() throws Exception {
+ Group group1 = new Group("group1");
+ Group group2 = new Group("group2");
+ Group group3 = new Group("group3");
+ groups.add(group1);
+ groups.add(group2);
+ groups.add(group3);
+
+ // user1 user2 user3
+ // group1 y
+ // group2 y y
+ // group3 y y y
+ User user1 = createUser("user1", PASSWORD, group1);
+ user1.addGroup(group2);
+ user1.addGroup(group3);
+
+ User user2 = createUser("user2", PASSWORD, group2);
+ user2.addGroup(group3);
+
+ User user3 = createUser("user3", PASSWORD, group3);
+ users.add(user1);
+ users.add(user2);
+ users.add(user3);
+
+ checkUserExists(user1.getName());
+ checkUserExists(user2.getName());
+ checkUserExists(user3.getName());
+
+ checkGroupExists(group1.getName());
+ checkGroupExists(group2.getName());
+ checkGroupExists(group3.getName());
+
+ checkUserCount(3);
+ checkGroupCount(3 + 1); // also count the group that was created in the
+ // setUp().
+
+ Set<User> list = users.list(group1);
+ assertTrue(list.contains(user1));
+ assertEquals(1, list.size());
+
+ list = users.list(group2);
+ assertTrue(list.contains(user1));
+ assertTrue(list.contains(user2));
+ assertEquals(2, list.size());
+
+ list = users.list(group3);
+ assertTrue(list.contains(user1));
+ assertTrue(list.contains(user2));
+ assertTrue(list.contains(user3));
+ assertEquals(3, list.size());
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.usermgt;
-import java.util.Set;
-
import junit.framework.TestCase;
import org.apache.log4j.Logger;
+
import org.wamblee.security.encryption.Md5HexMessageDigester;
+
import org.wamblee.usermgt.UserMgtException.Reason;
+import java.util.Set;
+
/**
* Test of user administration implementation.
- *
+ *
* @author Erik Brakkee
*/
public class UserAdministrationImplTest extends TestCase {
-
private static final Logger LOGGER = Logger
- .getLogger(UserAdministrationImplTest.class);
+ .getLogger(UserAdministrationImplTest.class);
private static final String USER1 = "piet";
private static final String GROUP2 = "runners";
- private UserAdministration _admin;
-
+ private UserAdministration admin;
/*
* (non-Javadoc)
@Override
protected void setUp() throws Exception {
super.setUp();
- _admin = createAdmin();
+ admin = createAdmin();
}
protected UserAdministration createAdmin() {
- UserSet users = new InMemoryUserSet( new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"),
- new Md5HexMessageDigester());
+ UserSet users = new InMemoryUserSet(new RegexpNameValidator(
+ RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD,
+ "Password must contain at least 6 characters"),
+ new Md5HexMessageDigester());
GroupSet groups = new InMemoryGroupSet();
+
return new UserAdministrationImpl(users, groups,
- new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
- Reason.INVALID_USERNAME, "Invalid user"),
- new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
- Reason.INVALID_GROUPNAME, "Invalid group"));
+ new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
+ Reason.INVALID_USERNAME, "Invalid user"),
+ new RegexpNameValidator(RegexpNameValidator.ID_PATTERN,
+ Reason.INVALID_GROUPNAME, "Invalid group"));
}
-
- protected User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException {
+
+ protected User createUser(String aName, String aPassword, Group aGroup)
+ throws UserMgtException {
return UsermgtTestUtils.createUser(aName, aPassword, aGroup);
}
* Constructs the admin, verify it contains no users and no groups.
*/
public void testConstruct() {
- assertEquals(0, _admin.getUsers().size());
- assertEquals(0, _admin.getGroups().size());
- assertEquals(0, _admin.getUserCount());
- assertEquals(0, _admin.getGroupCount());
+ assertEquals(0, admin.getUsers().size());
+ assertEquals(0, admin.getGroups().size());
+ assertEquals(0, admin.getUserCount());
+ assertEquals(0, admin.getGroupCount());
}
/**
*
*/
public void testCreateGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
assertNotNull(group);
assertEquals(GROUP1, group.getName());
- Set<Group> groups = _admin.getGroups();
+ Set<Group> groups = admin.getGroups();
assertEquals(1, groups.size());
- assertEquals(1, _admin.getGroupCount());
+ assertEquals(1, admin.getGroupCount());
assertTrue(groups.contains(group));
}
private void createInvalidGroup(String aUsername) {
try {
- _admin.createGroup(aUsername);
+ admin.createGroup(aUsername);
fail();
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.INVALID_GROUPNAME, e
- .getReason());
- assertEquals(0, _admin.getGroupCount());
+ .getReason());
+ assertEquals(0, admin.getGroupCount());
}
}
*
*/
public void testCreateDuplicateGroup() throws UserMgtException {
- _admin.createGroup(GROUP1);
+ admin.createGroup(GROUP1);
+
try {
- _admin.createGroup(GROUP1);
+ admin.createGroup(GROUP1);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
- assertEquals(1, _admin.getGroupCount());
+ assertEquals(1, admin.getGroupCount());
+
return;
}
+
fail();
}
*
*/
public void testCreateUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
assertNotNull(user);
assertEquals(USER1, user.getName());
user.checkPassword(PASS1);
- Set<User> users = _admin.getUsers();
+ Set<User> users = admin.getUsers();
assertEquals(1, users.size());
- assertEquals(1, _admin.getUserCount());
+ assertEquals(1, admin.getUserCount());
assertTrue(users.contains(user));
}
private void createInvalidUser(String aUsername, Group aGroup) {
try {
- _admin.createUser(aUsername, "pass", aGroup);
+ admin.createUser(aUsername, "pass", aGroup);
fail();
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.INVALID_USERNAME, e
- .getReason());
- assertEquals(0, _admin.getUserCount());
+ .getReason());
+ assertEquals(0, admin.getUserCount());
}
}
*
*/
public void testCreateInvalidUserName() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
createInvalidUser("", group);
createInvalidUser("0abc", group); // should not start with digits
createInvalidUser("a b", group); // should not contain spaces
*
*/
public void testCreateDuplicateUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ admin.createUser(USER1, PASS1, group);
+
try {
- _admin.createUser(USER1, PASS2, group);
+ admin.createUser(USER1, PASS2, group);
fail();
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
- assertEquals(1, _admin.getUserCount());
+ assertEquals(1, admin.getUserCount());
}
}
*
*/
public void testGetUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
- User user2 = _admin.getUser(USER1);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
+ User user2 = admin.getUser(USER1);
assertTrue(user.equals(user2));
- assertNull(_admin.getUser(USER2));
+ assertNull(admin.getUser(USER2));
}
/**
*
*/
public void testGetGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- Group group2 = _admin.getGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
+ Group group2 = admin.getGroup(GROUP1);
assertTrue(group.equals(group2));
- assertNull(_admin.getGroup(GROUP2));
+ assertNull(admin.getGroup(GROUP2));
}
/**
*
*/
public void testAddUserToGroup() throws UserMgtException {
-
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
- Group group2 = _admin.createGroup(GROUP2);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
+ Group group2 = admin.createGroup(GROUP2);
assertTrue(user.isInGroup(group));
assertFalse(user.isInGroup(group2));
- _admin.addUserToGroup(user, group2);
+ admin.addUserToGroup(user, group2);
assertTrue(user.isInGroup(group));
assertTrue(user.isInGroup(group2));
- Set<User> users = _admin.getUsers(group2);
+
+ Set<User> users = admin.getUsers(group2);
assertNotNull(users);
assertEquals(1, users.size());
assertTrue(users.contains(user));
try {
- _admin.addUserToGroup(user, group);
+ admin.addUserToGroup(user, group);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.USER_ALREADY_IN_GROUP, e
- .getReason());
+ .getReason());
+
return;
}
+
fail();
}
*
*/
public void testAddUserToGroupUnknownUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
User user = createUser(USER1, PASS1, group);
+
try {
- _admin.addUserToGroup(user, group);
+ admin.addUserToGroup(user, group);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
+
return;
}
+
fail();
}
*
*/
public void testAddUserToGroupUnknownGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
Group group2 = new Group(GROUP2);
+
try {
- _admin.addUserToGroup(user, group2);
+ admin.addUserToGroup(user, group2);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
+
return;
}
+
fail();
}
* Removes a user from a group. Verifies that the user is removed from the
* group using several API calls. Verifies that an exception occurs if the
* user not part of the group or if the user is only part of one group.
+ *
*/
public void testRemoveUserFromGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
+
+ User user = admin.createUser(USER1, PASS1, group);
+ Group group2 = admin.createGroup(GROUP2);
+ admin.addUserToGroup(user, group2);
- User user = _admin.createUser(USER1, PASS1, group);
- Group group2 = _admin.createGroup(GROUP2);
- _admin.addUserToGroup(user, group2);
Set<Group> groups = user.getGroups();
assertEquals(2, groups.size());
assertTrue(groups.contains(group));
assertTrue(groups.contains(group2));
- _admin.removeUserFromGroup(user, group);
+ admin.removeUserFromGroup(user, group);
groups = user.getGroups();
assertEquals(1, groups.size());
assertTrue(groups.contains(group2));
*
*/
public void testRemoveUserFromGroupUnknownUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
User user = createUser(USER1, GROUP1, group);
+
try {
- _admin.removeUserFromGroup(user, group);
+ admin.removeUserFromGroup(user, group);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
}
*
*/
public void testRemoveUserFromGroupUnknownGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
Group group2 = new Group(GROUP2);
+
try {
- _admin.removeUserFromGroup(user, group2);
+ admin.removeUserFromGroup(user, group2);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
}
/**
* Removes a user from a group where the user is only part of one group.
* Verifies that an exception is thrown.
+ *
*/
public void testRemoveUserFromGroupOnlyGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
+
try {
- _admin.removeUserFromGroup(user, group);
+ admin.removeUserFromGroup(user, group);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.USER_MUST_BE_IN_A_GROUP, e
- .getReason());
+ .getReason());
}
}
*
*/
public void testGetUsersAndGroups() throws UserMgtException {
- Group group1 = _admin.createGroup(GROUP1);
- Group group2 = _admin.createGroup(GROUP2);
+ Group group1 = admin.createGroup(GROUP1);
+ Group group2 = admin.createGroup(GROUP2);
- User user1 = _admin.createUser(USER1, PASS1, group1);
- _admin.addUserToGroup(user1, group2);
- User user2 = _admin.createUser(USER2, PASS2, group2);
+ User user1 = admin.createUser(USER1, PASS1, group1);
+ admin.addUserToGroup(user1, group2);
- Set<User> users = _admin.getUsers();
+ User user2 = admin.createUser(USER2, PASS2, group2);
+
+ Set<User> users = admin.getUsers();
assertEquals(2, users.size());
assertTrue(users.contains(user1));
assertTrue(users.contains(user2));
- Set<Group> groups = _admin.getGroups();
+ Set<Group> groups = admin.getGroups();
assertEquals(2, groups.size());
assertTrue(groups.contains(group1));
assertTrue(groups.contains(group2));
*
*/
public void testRenameUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user1 = _admin.createUser(USER1, PASS1, group);
- _admin.renameUser(user1, USER2);
+ Group group = admin.createGroup(GROUP1);
+ User user1 = admin.createUser(USER1, PASS1, group);
+ admin.renameUser(user1, USER2);
assertEquals(USER2, user1.getName());
- assertEquals(user1, _admin.getUser(USER2));
-
- _admin.createUser(USER1, PASS1, group);
+ assertEquals(user1, admin.getUser(USER2));
try {
- _admin.renameUser(user1, USER1);
+ admin.renameUser(user1, USER1);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.DUPLICATE_USER, e.getReason());
// do a trivial reanem
try {
- _admin.renameUser(user1, user1.getName());
+ admin.renameUser(user1, user1.getName());
} catch (UserMgtException e2) {
assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
- .getReason());
+ .getReason());
+
return;
}
+
fail();
}
+
fail();
}
*
*/
public void testRenameUserInvalidUsername() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user1 = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user1 = admin.createUser(USER1, PASS1, group);
+
try {
- _admin.renameUser(user1, USER2);
+ admin.renameUser(user1, USER2);
} catch (UserMgtException e) {
assertEquals(e.getReason(), Reason.INVALID_USERNAME);
}
*
*/
public void testRenameGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- _admin.renameGroup(group, GROUP2);
+ Group group = admin.createGroup(GROUP1);
+ admin.renameGroup(group, GROUP2);
assertEquals(GROUP2, group.getName());
- assertEquals(group, _admin.getGroup(GROUP2));
+ assertEquals(group, admin.getGroup(GROUP2));
+
+ admin.createGroup(GROUP1);
- _admin.createGroup(GROUP1);
try {
- _admin.renameGroup(group, GROUP1);
+ admin.renameGroup(group, GROUP1);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.DUPLICATE_GROUP, e.getReason());
// do a trivial reanem
try {
- _admin.renameGroup(group, group.getName());
+ admin.renameGroup(group, group.getName());
} catch (UserMgtException e2) {
assertEquals(UserMgtException.Reason.TRIVIAL_RENAME, e2
- .getReason());
+ .getReason());
+
return;
}
+
fail();
+
return;
}
+
fail();
}
*
*/
public void testRenameGroupInvalidGroupname() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
+
try {
- _admin.renameGroup(group, "a b");
+ admin.renameGroup(group, "a b");
} catch (UserMgtException e) {
assertEquals(e.getReason(), Reason.INVALID_GROUPNAME);
}
*
*/
public void testRemoveUser() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
- assertEquals(1, _admin.getUserCount());
- _admin.removeUser(user);
- assertEquals(0, _admin.getUserCount());
+ assertEquals(1, admin.getUserCount());
+ admin.removeUser(user);
+ assertEquals(0, admin.getUserCount());
- _admin.createUser(USER1, PASS1, group);
- assertEquals(1, _admin.getUserCount());
+ admin.createUser(USER1, PASS1, group);
+ assertEquals(1, admin.getUserCount());
User user2 = createUser(USER2, PASS2, group);
try {
- _admin.removeUser(user2);
+ admin.removeUser(user2);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.UNKNOWN_USER, e.getReason());
}
*
*/
public void testRemoveGroup() throws UserMgtException {
- Group group1 = _admin.createGroup(GROUP1);
- assertEquals(1, _admin.getGroupCount());
- _admin.removeGroup(group1);
- assertEquals(0, _admin.getGroupCount());
- group1 = _admin.createGroup(GROUP1);
+ Group group1 = admin.createGroup(GROUP1);
+ assertEquals(1, admin.getGroupCount());
+ admin.removeGroup(group1);
+ assertEquals(0, admin.getGroupCount());
+ group1 = admin.createGroup(GROUP1);
+
+ admin.createUser(USER1, PASS1, group1);
- _admin.createUser(USER1, PASS1, group1);
try {
- _admin.removeGroup(group1);
+ admin.removeGroup(group1);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.GROUP_STILL_OCCUPIED, e
- .getReason());
+ .getReason());
+
return;
}
+
fail();
}
*
*/
public void testRemoveGroupUnknownGroup() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
+ Group group = admin.createGroup(GROUP1);
Group group2 = new Group(GROUP2);
+
try {
- _admin.removeGroup(group2);
+ admin.removeGroup(group2);
} catch (UserMgtException e) {
assertEquals(UserMgtException.Reason.UNKNOWN_GROUP, e.getReason());
}
* @throws UserMgtException
*/
public void testChangePassword() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- User user = _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ User user = admin.createUser(USER1, PASS1, group);
user.changePassword(PASS1, PASS2);
// retrieve the user and verifies the password hasn't changed.
- User user2 = _admin.getUser(USER1);
+ User user2 = admin.getUser(USER1);
+
try {
user2.checkPassword(PASS2);
fail(); // password should not have changed already.
}
// now notify the admin of the change in the user
- _admin.userModified(user);
+ admin.userModified(user);
- user2 = _admin.getUser(USER1);
+ user2 = admin.getUser(USER1);
user2.checkPassword(PASS2); // this time it should succeed.
-
}
/**
*
*/
public void testPerformanceFindUserByName() throws UserMgtException {
- Group group = _admin.createGroup(GROUP1);
- _admin.createUser(USER1, PASS1, group);
+ Group group = admin.createGroup(GROUP1);
+ admin.createUser(USER1, PASS1, group);
int n = 1000;
long time = System.currentTimeMillis();
+
for (int i = 0; i < n; i++) {
- _admin.getUser(USER1);
+ admin.getUser(USER1);
}
- LOGGER.info("Looked up a user " + n + " times in "
- + (float) (System.currentTimeMillis() - time) / 1000.0);
- }
+ LOGGER.info("Looked up a user " + n + " times in " +
+ ((float) (System.currentTimeMillis() - time) / 1000.0));
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.usermgt;
import org.wamblee.security.encryption.Md5HexMessageDigester;
+
import org.wamblee.usermgt.UserMgtException.Reason;
/**
- * User management test utilities.
- *
+ * User management test utilities.
+ *
* @author Erik Brakkee
*/
public class UsermgtTestUtils {
-
private static final String DUMMY_GROUP = "dummygroup";
+
private static final String DUMMY_PASSWD = "dummypasswd";
- public static Group createGroup(String aName) {
+ public static Group createGroup(String aName) {
return new Group(aName);
}
-
- public static User createUser(String aUsername) throws UserMgtException {
+
+ public static User createUser(String aUsername) throws UserMgtException {
return createUser(aUsername, DUMMY_GROUP);
}
-
- public static User createUser(String aUsername, String aGroup) throws UserMgtException {
- return createUser(aUsername, createGroup(aGroup));
+
+ public static User createUser(String aUsername, String aGroup)
+ throws UserMgtException {
+ return createUser(aUsername, createGroup(aGroup));
}
-
- public static User createUser(String aUsername, Group aGroup) throws UserMgtException {
+
+ public static User createUser(String aUsername, Group aGroup)
+ throws UserMgtException {
return createUser(aUsername, DUMMY_PASSWD, aGroup);
}
-
- public static User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException {
- return new User(aName, aPassword, aGroup,
- new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN,
- Reason.INVALID_PASSWORD, "Password must be at least 6 chars"),
- new Md5HexMessageDigester());
+
+ public static User createUser(String aName, String aPassword, Group aGroup)
+ throws UserMgtException {
+ return new User(aName, aPassword, aGroup, new RegexpNameValidator(
+ RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD,
+ "Password must be at least 6 chars"), new Md5HexMessageDigester());
}
-
- public static void addUserToGroup(User aUser, Group aGroup) throws UserMgtException {
+
+ public static void addUserToGroup(User aUser, Group aGroup)
+ throws UserMgtException {
aUser.addGroup(aGroup);
}
-
- public static void removeUserFromGroup(User aUser, Group aGroup) throws UserMgtException {
+
+ public static void removeUserFromGroup(User aUser, Group aGroup)
+ throws UserMgtException {
aUser.removeGroup(aGroup);
}
}
--- /dev/null
+<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.wamblee</groupId>
+ <artifactId>wamblee-utils</artifactId>
+ <version>0.2.2</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-security-jpatest</artifactId>
+ <packaging>jar</packaging>
+ <name>/security/jpatest</name>
+ <url>http://wamblee.org</url>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ <version>3.5.0-Final</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-security-impl</artifactId>
+ <version>0.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-security-impl</artifactId>
+ <version>0.2.2</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-test-enterprise</artifactId>
+ <version>0.2.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.wamblee</groupId>
+ <artifactId>wamblee-test-hibernate</artifactId>
+ <version>0.2.2</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>jboss</id>
+ <name>JBoss Repo</name>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ </repositories>
+
+</project>
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.security.authorization.jpa;
+
+import javax.persistence.EntityManager;
+
+import org.apache.log4j.Logger;
+import org.wamblee.security.authorization.AbstractAuthorizationService;
+import org.wamblee.security.authorization.AllOperation;
+import org.wamblee.security.authorization.AuthorizationResult;
+import org.wamblee.security.authorization.AuthorizationService;
+import org.wamblee.security.authorization.AuthorizationServiceTest;
+import org.wamblee.security.authorization.TestAuthorizationRule;
+import org.wamblee.support.persistence.JpaTester;
+import org.wamblee.support.persistence.TransactionProxyFactory;
+import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
+import org.wamblee.usermgt.jpa.SecurityPersistenceUnit;
+
+/**
+ * Unit test for the persistent authorization service.
+ *
+ * @author Erik Brakkee
+ */
+public class JpaAuthorizationServiceTest extends AuthorizationServiceTest {
+ private static final Logger LOGGER = Logger
+ .getLogger(JpaAuthorizationServiceTest.class);
+
+ private static final String SERVICE_TABLE = "SEC_AUTH_SVC";
+
+ private static final String RULES_TABLE = "SEC_AUTH_RULE";
+
+ private static final String SERVICE_RULES_TABLE = "SEC_AUTH_SVC_SEC_AUTH_RULE";
+
+ private static final String OPERATIONCOND_TABLE = "SEC_OPERATION_CONDITION";
+
+ private static final String PATHCOND_TABLE = "SEC_PATH_CONDITION";
+
+ private static final String USERCOND_TABLE = "SEC_USER_CONDITION";
+
+ private JpaTester jpaTester;
+
+ private AuthorizationService authorizationService;
+
+ @Override
+ protected void setUp() throws Exception {
+ jpaTester = new JpaTester(new SecurityPersistenceUnit());
+ jpaTester.start();
+
+ super.setUp();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationServiceTest#createService
+ * ()
+ */
+ @Override
+ protected AuthorizationService createService() {
+ TransactionProxyFactory<AuthorizationService> factory = new TransactionProxyFactory<AuthorizationService>(
+ jpaTester.getJpaBuilder(), AuthorizationService.class);
+ JpaAuthorizationService service = new JpaAuthorizationService(
+ "DEFAULT", factory.getTransactionScopedEntityManager(),
+ createUserAccessor(), 10000);
+
+ return factory.getProxy(service);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.security.authorization.AuthorizationServiceTest#checkRuleCount
+ * (int)
+ */
+ @Override
+ protected void checkRuleCount(int aCount) {
+ try {
+ assertEquals(1, jpaTester.getDbUtils().getTableSize(SERVICE_TABLE));
+ assertEquals(aCount, jpaTester.getDbUtils().getTableSize(
+ RULES_TABLE));
+ assertEquals(aCount, jpaTester.getDbUtils().getTableSize(
+ SERVICE_RULES_TABLE));
+ assertEquals(aCount, jpaTester.getDbUtils().getTableSize(
+ USERCOND_TABLE));
+ assertEquals(aCount, jpaTester.getDbUtils().getTableSize(
+ PATHCOND_TABLE));
+ assertEquals(aCount, jpaTester.getDbUtils().getTableSize(
+ OPERATIONCOND_TABLE));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void testPerformance() {
+ int n = 1000;
+ long time = System.currentTimeMillis();
+
+ for (int i = 0; i < n; i++) {
+ testFirstRuleGrants();
+ resetTestRules();
+ testSecondRuleDenies();
+ resetTestRules();
+ testThirdRuleGrants();
+ resetTestRules();
+ testNoRulesSupportResource();
+ }
+
+ LOGGER.info("Executed " + (4 * n) + " authorization checks in " +
+ ((float) (System.currentTimeMillis() - time) / (float) 1000) +
+ " seconds.");
+ }
+}
--- /dev/null
+package org.wamblee.usermgt.jpa;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.wamblee.support.persistence.JpaTester;
+import org.wamblee.support.persistence.TransactionProxyFactory;
+import org.wamblee.support.persistence.DatabaseUtils.JdbcUnitOfWork;
+import org.wamblee.usermgt.GroupSet;
+import org.wamblee.usermgt.InMemoryGroupSetTest;
+
+
+public class JpaGroupSetTest extends InMemoryGroupSetTest {
+
+ private static final String GROUP_TABLE = "SEC_GROUP";
+
+ private static final String GROUP_QUERY = "select * from " + GROUP_TABLE +
+ " where name = ?";
+
+ private JpaTester jpaTester;
+
+ @Before
+ public void setUp() throws Exception {
+ jpaTester = new JpaTester(new SecurityPersistenceUnit());
+ jpaTester.start();
+
+ // Superclass setup will call createGroupSet so requires initialized JPA.
+ super.setUp();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ jpaTester.stop();
+ super.tearDown();
+ }
+
+ @Override
+ protected void checkGroupCount(int aSize) throws Exception {
+ super.checkGroupCount(aSize);
+ assertEquals(aSize, jpaTester.getDbUtils().getTableSize(GROUP_TABLE));
+ }
+
+ @Override
+ protected void checkGroupExists(String aGroup) throws Exception {
+ super.checkGroupExists(aGroup);
+ assertTrue(groupExists(aGroup));
+ }
+
+ private boolean groupExists(final String aGroup) throws Exception {
+ return jpaTester.getDbUtils().executeInTransaction(
+ new JdbcUnitOfWork<Boolean>() {
+ @Override
+ public Boolean execute(Connection aConnection) throws Exception {
+ ResultSet res = jpaTester.getDbUtils().executeQuery(
+ aConnection, GROUP_QUERY, aGroup);
+ return res.next();
+ }
+ });
+ }
+
+ @Override
+ protected void checkGroupNotExists(String aGroup) throws Exception {
+ super.checkGroupNotExists(aGroup);
+ assertFalse(groupExists(aGroup));
+ }
+
+ @Override
+ protected GroupSet createGroupSet() {
+ TransactionProxyFactory<GroupSet> factory = new TransactionProxyFactory<GroupSet>(
+ jpaTester.getJpaBuilder(), GroupSet.class);
+ GroupSet groupset = new JpaGroupSet(factory.getTransactionScopedEntityManager());
+ GroupSet proxy = factory.getProxy(groupset);
+ return proxy;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt.jpa;
+
+import java.lang.reflect.Method;
+import java.sql.Connection;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wamblee.cache.EhCache;
+import org.wamblee.io.ClassPathResource;
+import org.wamblee.security.encryption.Md5HexMessageDigester;
+import org.wamblee.security.encryption.MessageDigester;
+import org.wamblee.support.persistence.JpaTester;
+import org.wamblee.support.persistence.TransactionProxyFactory;
+import org.wamblee.support.persistence.DatabaseUtils.JdbcUnitOfWork;
+import org.wamblee.usermgt.GroupSet;
+import org.wamblee.usermgt.NameValidator;
+import org.wamblee.usermgt.RegexpNameValidator;
+import org.wamblee.usermgt.User;
+import org.wamblee.usermgt.UserAdministration;
+import org.wamblee.usermgt.UserAdministrationImpl;
+import org.wamblee.usermgt.UserAdministrationImplTest;
+import org.wamblee.usermgt.UserSet;
+
+/**
+ * User administration tests with persistence based on Hibernate. This executes
+ * the same test cases as {@link org.wamblee.usermgt.UserAdministrationImplTest}
+ * with in addition, one test case that executes all Hibernate test cases
+ * separately with each test case in its own transaction.
+ *
+ * @author Erik Brakkee
+ */
+public class JpaUserAdministrationTest extends UserAdministrationImplTest {
+ private static final Log LOG = LogFactory
+ .getLog(JpaUserAdministrationTest.class);
+
+ private JpaTester jpaTester;
+
+ private EhCache<String, User> userCache;
+
+ private UserAdministration userAdmin;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.UserAdministrationImplTest#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ jpaTester = new JpaTester(new SecurityPersistenceUnit());
+ jpaTester.start();
+
+ userCache = new EhCache<String, User>(new ClassPathResource(
+ "properties/org.wamblee.security.ehcache.xml"), "users");
+
+ TransactionProxyFactory<UserAdministration> factory = new TransactionProxyFactory<UserAdministration>(
+ jpaTester.getJpaBuilder(), UserAdministration.class);
+
+ NameValidator passwordValidator = new RegexpNameValidator(".{5,}",
+ "INVALID_PASSWORD", "Password must have at least 5 characters");
+ MessageDigester passwordDigester = new Md5HexMessageDigester();
+ UserSet userset = new JpaUserSet(userCache, passwordValidator,
+ passwordDigester, factory.getTransactionScopedEntityManager());
+ GroupSet groupset = new JpaGroupSet(factory
+ .getTransactionScopedEntityManager());
+
+ NameValidator userValidator = new RegexpNameValidator(
+ "[a-zA-Z]+[a-zA-Z0-9]*", "INVALID_USERNAME", "");
+ NameValidator groupValidator = new RegexpNameValidator(
+ "[a-zA-Z]+[a-zA-Z0-9]*", "INVALID_GROUPNAME", "");
+ UserAdministration userAdminImpl = new UserAdministrationImpl(userset,
+ groupset, userValidator, groupValidator);
+ userAdmin = factory.getProxy(userAdminImpl);
+
+ super.setUp();
+ clearUserCache();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ jpaTester.stop();
+ super.tearDown();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.UserAdministrationImplTest#createAdmin()
+ */
+ @Override
+ protected UserAdministration createAdmin() {
+ return userAdmin;
+ }
+
+ public void testAllTestsInASeparateTransaction() throws Exception {
+ Method[] methods = UserAdministrationImplTest.class.getMethods();
+
+ for (final Method method : methods) {
+ if (method.getName().startsWith("test")) {
+ jpaTester.getDbUtils().cleanDatabase();
+ clearUserCache();
+ jpaTester.getDbUtils().executeInTransaction(
+ new JdbcUnitOfWork<Void>() {
+ @Override
+ public Void execute(Connection aConnection)
+ throws Exception {
+ LOG.info("Running test " + method.getName());
+
+ try {
+ method.invoke(JpaUserAdministrationTest.this);
+ } catch (Throwable t) {
+ LOG.error("Test " + method.getName() +
+ " failed");
+ throw new RuntimeException(t.getMessage(), t);
+ } finally {
+ LOG.info("Test " + method.getName() +
+ " finished");
+ }
+ return null;
+ }
+ });
+ }
+ }
+ }
+
+ private void clearUserCache() {
+ userCache.clear();
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.usermgt.jpa;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.Set;
+
+import org.wamblee.cache.EhCache;
+import org.wamblee.io.ClassPathResource;
+import org.wamblee.security.encryption.Md5HexMessageDigester;
+import org.wamblee.security.encryption.MessageDigester;
+import org.wamblee.support.persistence.JpaTester;
+import org.wamblee.support.persistence.TransactionProxyFactory;
+import org.wamblee.support.persistence.DatabaseUtils.JdbcUnitOfWork;
+import org.wamblee.usermgt.Group;
+import org.wamblee.usermgt.GroupSet;
+import org.wamblee.usermgt.InMemoryUserSetTest;
+import org.wamblee.usermgt.NameValidator;
+import org.wamblee.usermgt.RegexpNameValidator;
+import org.wamblee.usermgt.User;
+import org.wamblee.usermgt.UserSet;
+
+/**
+ * Tests for {@link org.wamblee.usermgt.hibernate.HibernateGroupSet}
+ *
+ * @author Erik Brakkee
+ */
+public class JpaUserSetTest extends InMemoryUserSetTest {
+ private static final String USER_TABLE = "SEC_USER";
+
+ private static final String GROUP_TABLE = "SEC_GROUP";
+
+ private static final String USER_QUERY = "select * from " + USER_TABLE +
+ " where name = ?";
+
+ private static final String GROUP_QUERY = "select * from " + GROUP_TABLE +
+ " where name = ?";
+
+ private UserSet userset;
+
+ private GroupSet groupset;
+
+ private EhCache<String, User> userCache;
+
+ private JpaTester jpaTester;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.InMemoryUserSetTest#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ jpaTester = new JpaTester(new SecurityPersistenceUnit());
+ jpaTester.start();
+
+ userCache = new EhCache<String, User>(
+ new ClassPathResource("properties/org.wamblee.security.ehcache.xml"), "users");
+
+ userset = createUserSetImpl();
+ groupset = createGroupSetImpl();
+
+ clearUserCache();
+
+ super.setUp();
+ }
+
+ private UserSet createUserSetImpl() {
+ NameValidator passwordValidator = new RegexpNameValidator(
+ ".{5,}", "INVALID_PASSWORD", "Password must have at least 5 characters");
+
+ MessageDigester passwordDigester = new Md5HexMessageDigester();
+ TransactionProxyFactory<UserSet> factory = new TransactionProxyFactory<UserSet>(
+ jpaTester.getJpaBuilder(), UserSet.class);
+ UserSet jpaUserset = new JpaUserSet(userCache, passwordValidator, passwordDigester,
+ factory.getTransactionScopedEntityManager());
+ return factory.getProxy(jpaUserset);
+ }
+
+ private GroupSet createGroupSetImpl() {
+ TransactionProxyFactory<GroupSet> factory = new TransactionProxyFactory<GroupSet>(
+ jpaTester.getJpaBuilder(), GroupSet.class);
+ GroupSet groupset = new JpaGroupSet(factory.getTransactionScopedEntityManager());
+ GroupSet proxy = factory.getProxy(groupset);
+ return proxy;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ jpaTester.stop();
+ super.tearDown();
+ }
+
+ /**
+ * Clears the user cache.
+ */
+ private void clearUserCache() {
+ userCache.clear();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupCount(int)
+ */
+ @Override
+ protected void checkUserCount(int aSize) throws Exception {
+ super.checkUserCount(aSize);
+ assertEquals(aSize, jpaTester.getDbUtils().getTableSize(USER_TABLE));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupExists(java.lang.String
+ * )
+ */
+ @Override
+ protected void checkUserExists(final String aUser) throws Exception {
+ assertEquals(1, countUser(aUser));
+ }
+
+ private int countUser(final String aUser) throws Exception {
+ int count = jpaTester.getDbUtils().executeInTransaction(new JdbcUnitOfWork<Integer>() {
+ @Override
+ public Integer execute(Connection aConnection) throws Exception {
+ ResultSet res = jpaTester.getDbUtils().executeQuery(aConnection, USER_QUERY, aUser);
+ return jpaTester.getDbUtils().countResultSet(res);
+ }
+ });
+ return count;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupNotExists(java.lang
+ * .String)
+ */
+ @Override
+ protected void checkUserNotExists(String aUser) throws Exception {
+ assertEquals(0, countUser(aUser));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupCount(int)
+ */
+ @Override
+ protected void checkGroupCount(int aSize) throws Exception {
+ assertEquals(aSize, jpaTester.getDbUtils().getTableSize(GROUP_TABLE));
+ }
+
+ private int countGroup(final String aGroup) throws Exception {
+ int count = jpaTester.getDbUtils().executeInTransaction(new JdbcUnitOfWork<Integer>() {
+ @Override
+ public Integer execute(Connection aConnection) throws Exception {
+ ResultSet res = jpaTester.getDbUtils().executeQuery(aConnection, GROUP_QUERY, aGroup);
+ return jpaTester.getDbUtils().countResultSet(res);
+ }
+ });
+ return count;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupExists(java.lang.String
+ * )
+ */
+ @Override
+ protected void checkGroupExists(String aGroup) throws Exception {
+ assertEquals(1, countGroup(aGroup));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupNotExists(java.lang
+ * .String)
+ */
+ @Override
+ protected void checkGroupNotExists(String aGroup) throws Exception {
+ assertEquals(0, countGroup(aGroup));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.InMemoryGroupSetTest#createGroupSet()
+ */
+ @Override
+ protected UserSet createUserSet() {
+ return userset;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.usermgt.InMemoryUserSetTest#createGroupSet()
+ */
+ @Override
+ protected GroupSet createGroupSet() {
+ return groupset;
+ }
+
+ /**
+ * Reproduction of a bug. Create a user which is in group1 Add it to a
+ * second group group2. Remove the user from group1. Verify the user is in
+ * group2.
+ *
+ */
+ public void testVerifyAddRemove() throws Exception {
+ jpaTester.getDbUtils().cleanDatabase(); // super class setup always creates one group.
+
+ GroupSet groups = getGroups();
+ assertEquals(0, groups.size());
+
+ Group group1 = createGroup("group1");
+ Group group2 = createGroup("group2");
+ groups.add(group1);
+ groups.add(group2);
+ checkGroupExists("group1");
+ checkGroupExists("group2");
+
+ User user = createUser("user", PASSWORD, group1);
+ getUsers().add(user);
+ checkUserExists("user");
+
+ addUserToGroup(user, group2);
+ getUsers().userModified(user);
+ clearUserCache();
+
+ User user2 = getUsers().find("user");
+
+ Set<Group> userGroups = user2.getGroups();
+ assertTrue(user2.isInGroup("group1"));
+ assertTrue(user2.isInGroup("group2"));
+ assertEquals(2, userGroups.size());
+
+ removeUserFromGroup(user, group1);
+ getUsers().userModified(user);
+ clearUserCache();
+ user2 = getUsers().find("user");
+ userGroups = user2.getGroups();
+ assertFalse(user2.isInGroup("group1"));
+ assertTrue(user2.isInGroup("group2"));
+ assertEquals(1, userGroups.size());
+ }
+}
--- /dev/null
+package org.wamblee.usermgt.jpa;
+
+import org.dbunit.dataset.DataSetException;
+import org.dbunit.dataset.filter.ITableFilterSimple;
+import org.wamblee.support.persistence.PersistenceUnitDescription;
+
+public class SecurityPersistenceUnit extends PersistenceUnitDescription {
+
+ public SecurityPersistenceUnit() {
+ super("jdbc/security", "securitytest", new ITableFilterSimple() {
+
+ @Override
+ public boolean accept(String aTableName) throws DataSetException {
+ return aTableName.startsWith("SEC_");
+ }
+ });
+ }
+}
--- /dev/null
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+ version="2.0">
+
+ <persistence-unit name="securitytest">
+ <jta-data-source>jdbc/security</jta-data-source>
+
+ <class>org.wamblee.usermgt.User</class>
+ <class>org.wamblee.usermgt.Group</class>
+ <class>org.wamblee.security.authorization.AbstractUserCondition</class>
+ <class>org.wamblee.security.authorization.AnyUserCondition</class>
+ <class>org.wamblee.security.authorization.GroupUserCondition</class>
+ <class>org.wamblee.security.authorization.AbstractOperationCondition</class>
+ <class>org.wamblee.security.authorization.IsaOperationCondition</class>
+ <class>org.wamblee.security.authorization.AbstractPathCondition</class>
+ <class>org.wamblee.security.authorization.RegexpPathCondition</class>
+ <class>org.wamblee.security.authorization.StartsWithPathCondition</class>
+ <class>org.wamblee.security.authorization.AbstractAuthorizationRule</class>
+ <class>org.wamblee.security.authorization.UrlAuthorizationRule</class>
+ <class>org.wamblee.security.authorization.TestAuthorizationRule</class>
+ <class>org.wamblee.security.authorization.AbstractAuthorizationService</class>
+ <class>org.wamblee.security.authorization.DefaultAuthorizationService</class>
+
+ <exclude-unlisted-classes>true</exclude-unlisted-classes>
+
+ </persistence-unit>
+</persistence>
\ No newline at end of file
<modelVersion>4.0.0</modelVersion>
<groupId>org.wamblee</groupId>
<artifactId>wamblee-security</artifactId>
- <packaging>jar</packaging>
+ <packaging>pom</packaging>
<name>/security</name>
<url>http://wamblee.org</url>
- <dependencies>
-
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-support-general</artifactId>
- <version>0.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-support-general</artifactId>
- <type>test-jar</type>
- <version>0.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-test-enterprise</artifactId>
- <version>0.2.2</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-system-spring</artifactId>
- <version>0.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-system-spring</artifactId>
- <type>test-jar</type>
- <version>0.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-system-general</artifactId>
- <type>test-jar</type>
- <version>0.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-support-spring</artifactId>
- <version>0.2.2</version>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-support-spring</artifactId>
- <type>test-jar</type>
- <version>0.2.2</version>
- </dependency>
-
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-hibernate-jpa</artifactId>
- <version>0.2.2</version>
- </dependency>
-
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-hibernate3</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- </dependency>
- <dependency>
- <groupId>javax.transaction</groupId>
- <artifactId>transaction-api</artifactId>
- <version>1.1</version>
- <scope>test</scope>
- </dependency>
-
- </dependencies>
+ <modules>
+ <module>impl</module>
+ </modules>
+
+ <profiles>
+ <profile>
+ <id>all</id>
+ <activation>
+ <property>
+ <name>!performRelease</name>
+ </property>
+ </activation>
+ <modules>
+ <module>jpatest</module>
+ </modules>
+ </profile>
+ </profiles>
+
+
</project>
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import org.wamblee.persistence.Persistent;
-
-/**
- * Service to determine if access to a certain resource is allowed.
- *
- * @author Erik Brakkee
- */
-public interface AuthorizationService extends Persistent {
-
- /**
- * Checks whether an operation is allowed on a resource.
- * @param aResource Resource.
- * @param aOperation Operation.
- * @return Checks whether the operation is allowed on a resource.
- */
- boolean isAllowed(Object aResource, Operation aOperation);
-
- /**
- * Same as {@link #isAllowed(Object, Operation)} but throws a
- * <code>RuntimeException</code> in case access is not allowed.
- * @param aResource Resource to check.
- * @param aOperation Operation to perform.
- * @return Resource that was checked.
- */
- <T> T check(T aResource, Operation aOperation);
-
- /**
- * Gets the authorization rules.
- * @return Rules.
- */
- AuthorizationRule[] getRules();
-
- /**
- * Appends a new authorization rule to the end.
- * @param aRule Rule to append.
- */
- void appendRule(AuthorizationRule aRule);
-
- /**
- * Removes a rule.
- * @param aRule Index of the rule to remove.
- */
- void removeRule(int aIndex);
-
- /**
- * Inserts a rule.
- * @param aIndex Index of the position of the rule after insertion.
- * @param aRule Rule to insert.
- */
- void insertRuleAfter(int aIndex, AuthorizationRule aRule);
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.wamblee.persistence.AbstractPersistent;
-import org.wamblee.usermgt.User;
-import org.wamblee.usermgt.UserAccessor;
-
-/**
- * Default implementation of an authorization service.
- * To determine whether access to a resource is allowed, the service consults a number
- * of authorization rules in a fixed order. The first rule that gives a result GRANTED or
- * DENIED determines the result of the evaluation. Rules that return any other result are
- * ignoed. If none of the rules match, than access is denied.
- *
- * @author Erik Brakkee
- */
-public class DefaultAuthorizationService extends AbstractPersistent implements AuthorizationService {
-
- /**
- * List of ordered authorization rules.
- */
- private List<AuthorizationRule> _rules;
-
- /**
- * User accessor used to obtain the current user.
- */
- private UserAccessor _userAccessor;
-
- /**
- * Name for this instance of the authorization service.
- */
- private String _name;
-
- /**
- * Constructs the service.
- * @param aAccessor User accessor.
- * @param aName Name of this instance of the service.
- */
- public DefaultAuthorizationService(UserAccessor aAccessor, String aName) {
- _rules = new ArrayList<AuthorizationRule>();
- _userAccessor = aAccessor;
- _name = aName;
- }
-
- /**
- * Constructs the authorization service.
- */
- public DefaultAuthorizationService() {
- _rules = new ArrayList<AuthorizationRule>();
- _userAccessor = null;
- _name = null;
- }
-
- /**
- * Sets the user accessor.
- * @param aUserAccessor User accessor.
- */
- public void setUserAccessor(UserAccessor aUserAccessor) {
- _userAccessor = aUserAccessor;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#isAllowed(java.lang.Object, org.wamblee.security.authorization.Operation)
- */
- public boolean isAllowed(Object aResource, Operation aOperation) {
- User user = _userAccessor.getCurrentUser();
- for (AuthorizationRule rule: _rules) {
- switch ( rule.isAllowed(aResource, aOperation, user)) {
- case DENIED: { return false; }
- case GRANTED: { return true; }
- }
- }
- return false;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#check(T, org.wamblee.security.authorization.Operation)
- */
- public <T> T check(T aResource, Operation aOperation) {
- if ( !isAllowed(aResource, aOperation)) {
- throw new AuthorizationException(aResource, aOperation);
- }
- return aResource;
- }
-
- protected String getName() {
- return _name;
- }
-
- public void setName(String aName) {
- _name = aName;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#getRules()
- */
- public AuthorizationRule[] getRules() {
- return _rules.toArray(new AuthorizationRule[0]);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#appendRule(org.wamblee.security.authorization.AuthorizationRule)
- */
- public void appendRule(AuthorizationRule aRule) {
- _rules.add(aRule);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#insertRuleAfter(int, org.wamblee.security.authorization.AuthorizationRule)
- */
- public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
- _rules.add(aIndex, aRule);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#removeRule(int)
- */
- public void removeRule(int aIndex) {
- _rules.remove(aIndex);
- }
-
- /**
- * For OR mapping.
- * @return The rules.
- */
- protected List<AuthorizationRule> getMappedRules() {
- return _rules;
- }
-
- /**
- * For OR mapping.
- * @param aRules The rules.
- */
- protected void setMappedRules(List<AuthorizationRule> aRules) {
- _rules = aRules;
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Operation registry implementation.
- * This implementation ignores the distinction between different types of resources
- * and simply assumes that every operation is applicable to every type of resource.
- *
- * @author Erik Brakkee
- */
-public class DefaultOperationRegistry implements OperationRegistry {
-
- private Map<String,Operation> _operations;
-
- public DefaultOperationRegistry(Operation[] aOperations) {
- _operations = new TreeMap<String, Operation>();
- for (Operation operation: aOperations) {
- _operations.put(operation.getName(), operation);
- }
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.OperationRegistry#getOperations(java.lang.Class)
- */
- public Operation[] getOperations(Class aResourceClass) {
- return _operations.values().toArray(new Operation[0]);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.OperationRegistry#encode(org.wamblee.security.authorization.Operation[])
- */
- public String encode(Operation[] aOperations) {
- StringBuffer buffer = new StringBuffer();
- for (Operation operation: aOperations) {
- if ( buffer.length() > 0 ) {
- buffer.append(',');
- }
- buffer.append(operation.getName());
- }
- return buffer.toString();
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.OperationRegistry#decode(java.lang.Class, java.lang.String)
- */
- public Operation[] decode(Class aResourceClass, String aOperationsString) {
- return decode(aOperationsString);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.OperationRegistry#decode(java.lang.String)
- */
- public Operation[] decode(String aOperationsString) {
- if ( aOperationsString.length() == 0 ) {
- return new Operation[0];
- }
- String[] names = aOperationsString.split(",");
- ArrayList<Operation> result = new ArrayList<Operation>();
- for (String name: names) {
- Operation operation = _operations.get(name);
- if ( operation == null ) {
- throw new IllegalArgumentException("Unknown operation '" + name + "'");
- }
- result.add(operation);
- }
- return result.toArray(new Operation[0]);
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import org.wamblee.persistence.AbstractPersistent;
-import org.wamblee.usermgt.User;
-
-/**
- * Checks if a user against a specific group.
- *
- * @author Erik Brakkee
- */
-public class GroupUserCondition extends AbstractPersistent implements UserCondition {
-
- /**
- * Group the user must be in.
- */
- private String _group;
-
- /**
- * Constructs the condition.
- * @param aGroup Group the user must be in.
- */
- public GroupUserCondition(String aGroup) {
- _group = aGroup;
- }
-
- /**
- * For OR mapping.
- *
- */
- protected GroupUserCondition() {
- _group = null;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.UserCondition#matches(org.wamblee.usermgt.UserAccessor)
- */
- public boolean matches(User aUser) {
- return aUser.isInGroup(_group);
- }
-
- /**
- * @return Returns the _group.
- */
- protected String getGroup() {
- return _group;
- }
-
- /**
- * @param _group The _group to set.
- */
- protected void setGroup(String aGroup) {
- _group = aGroup;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "GroupUserCondition(group=" + _group + ")";
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import org.wamblee.persistence.AbstractPersistent;
-
-/**
- * Condition to check whether a path matches a given regula expression.
- *
- * @author Erik Brakkee
- */
-public class RegexpPathCondition extends AbstractPersistent implements PathCondition {
-
- /**
- * String the path must start with.
- */
- private String _pattern;
-
- /**
- * Constructs the condition.
- * @param aPattern String the path must start with.
- */
- public RegexpPathCondition(String aPattern) {
- _pattern = aPattern;
- }
-
- /**
- * For OR mapping.
- *
- */
- protected RegexpPathCondition() {
- _pattern = null;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.PathCondition#matches(java.lang.String)
- */
- public boolean matches(String aPath) {
- return aPath.matches(_pattern);
- }
-
- /**
- * @return Returns the _path.
- */
- protected String getPattern() {
- return _pattern;
- }
-
- /**
- * @param aPattern The _path to set.
- */
- protected void setPattern(String aPattern) {
- _pattern = aPattern;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "RegexpCondition(pattern = '" + _pattern + "')";
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
-import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
-import static org.wamblee.security.authorization.AuthorizationResult.UNDECIDED;
-import static org.wamblee.security.authorization.AuthorizationResult.UNSUPPORTED_RESOURCE;
-
-import org.apache.log4j.Logger;
-import org.wamblee.persistence.AbstractPersistent;
-import org.wamblee.usermgt.User;
-
-/**
- * Utility base class for implementation of authentication rules based on the
- * <ul>
- * <li> The path of the resource. To obtain the path of a resource, subclasses
- * must implement {@link #getResourcePath(Object)}.
- * Whether a path is appropriate is determined by a
- * {@link org.wamblee.security.authorization.PathCondition}.
- * </li>
- * <li> The user identity with which the resource is accessed.
- * Whether a user is appropriate is determined by
- * a {@link org.wamblee.security.authorization.UserCondition}.
- * </li>
- * <li> The operation that is requested.
- * Whether the operation is appropriate is determined by a
- * {@link org.wamblee.security.authorization.OperationCondition}.
- * </li>
- * </ul>
- *
- * In case all three conditions match, the condition returns the configured
- * result passed at construction (GRANTED or DENIED). If the resource is not
- * of the specified type, the result is UNSUPPORTED_RESOURCE, otherwise, the
- * result is UNDECIDED.
- */
-public abstract class UrlAuthorizationRule extends AbstractPersistent implements AuthorizationRule {
-
- private static final Logger LOGGER = Logger.getLogger(UrlAuthorizationRule.class);
-
- /**
- * Result that the rule will return in case there is a match.
- */
- private AuthorizationResult _result;
-
- /**
- * A condition which specifies which users the rule is for.
- */
- private UserCondition _userCondition;
-
- /**
- * Path the rule applies for.
- */
- private PathCondition _pathCondition;
-
- /**
- * Resource class that the rule applies for.
- */
- private Class _resourceClass;
-
- /**
- * Operation that this rule is for.
- */
- private OperationCondition _operationCondition;
-
- /**
- * Constructs an authorization rule.
- * IF the group and path match, then the provided result will be returned.
- * @param aResult Result of the authorization when the path and group match.
- * @param aUserCondition Condition to match users.
- * @param aPathCondition Condition to match paths with.
- * @param aResourceClass Supported resource class this is for.
- * @param aOperationCondition Condition to match the operation with.
- */
- protected UrlAuthorizationRule(AuthorizationResult aResult, UserCondition aUserCondition,
- PathCondition aPathCondition, Class aResourceClass, OperationCondition aOperationCondition) {
- if ( !aResult.equals(GRANTED) && !aResult.equals(DENIED)) {
- throw new IllegalArgumentException("Only GRANTED or DENIED may be used: " + aResult);
- }
- _result = aResult;
- _userCondition = aUserCondition;
- _pathCondition = aPathCondition;
- _resourceClass = aResourceClass;
- _operationCondition = aOperationCondition;
- }
-
- /**
- * For OR mapping.
- *
- */
- protected UrlAuthorizationRule(Class aResourceClass) {
- _result = null;
- _userCondition = null;
- _pathCondition = null;
- _resourceClass = aResourceClass;
- _operationCondition = null;
- }
-
- /**
- * For OR mapping.
- *
- */
- protected UrlAuthorizationRule() {
- _result = null;
- _userCondition = null;
- _pathCondition = null;
- _resourceClass = null;
- _operationCondition = null;
- }
-
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationRule#getSupportedTypes()
- */
- public Class[] getSupportedTypes() {
- return new Class[] { _resourceClass };
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationRule#isAllowed(java.lang.Object,
- * org.wamblee.security.authorization.Operation)
- */
- public AuthorizationResult isAllowed(Object aResource, Operation anOperation, User aUser) {
- if ( ! _resourceClass.isInstance(aResource)) {
- return UNSUPPORTED_RESOURCE;
- }
- String path = getResourcePath(aResource);
- return isAllowed(path, anOperation, aUser);
- }
-
- /**
- * Determines if the operation is allowed on the resource.
- * @param aPath Path of the resource.
- * @param aOperation Operation to be done.
- * @param aUser Currently logged in user or null if no user is logged in.
- * @return Authorization result,
- */
- protected AuthorizationResult isAllowed(String aPath, Operation aOperation, User aUser) {
- if ( ! _pathCondition.matches(aPath) ) {
- return UNDECIDED;
- }
- if ( !_operationCondition.matches(aOperation) ) {
- return UNDECIDED;
- }
- if ( !_userCondition.matches(aUser)) {
- return UNDECIDED;
- }
- return _result;
- }
-
- /**
- * Gets the path of the resource.
- * @param aResource Resource, guaranteed to be an instance of
- * {@link #_resourceClass}.
- * @return Path of the resource.
- */
- protected abstract String getResourcePath(Object aResource);
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "UrlAUthorizationRule(result = " + _result +
- ", pathCondition = " + _pathCondition +
- ", userCondition = " + _userCondition +
- ", resourceClass = " + _resourceClass + ")";
- }
-
- /**
- * Gets the authorization result for OR mapping.
- * @return Result.
- */
- protected String getAuthorizationResultString() {
- if ( _result == null ) {
- return null;
- }
- return _result.toString();
- }
-
- /**
- * Sets the authorization result, for OR mapping.
- * @param aResult Result.
- */
- protected void setAuthorizationResultString(String aResult) {
- _result = AuthorizationResult.valueOf(aResult);
- }
-
- protected String getResourceClassName() {
- if ( _resourceClass == null ) {
- return "";
- }
- return _resourceClass.getName();
- }
-
- protected void setResourceClassName(String aResourceClass) {
- try {
- _resourceClass = Class.forName(aResourceClass);
- } catch (ClassNotFoundException e) {
- LOGGER.error("Cannot find resource class '" + aResourceClass + "'", e);
- throw new IllegalArgumentException(e.getMessage(), e);
- }
- }
-
- /**
- * @return Returns the _operationCondition.
- */
- public OperationCondition getOperationCondition() {
- return _operationCondition;
- }
-
- /**
- * @param aOperationCondition The _operationCondition to set.
- */
- protected void setOperationCondition(OperationCondition aOperationCondition) {
- _operationCondition = aOperationCondition;
- }
-
- /**
- * @return Returns the _pathCondition.
- */
- public PathCondition getPathCondition() {
- return _pathCondition;
- }
-
- /**
- * @param aPathCondition The _pathCondition to set.
- */
- protected void setPathCondition(PathCondition aPathCondition) {
- _pathCondition = aPathCondition;
- }
-
- /**
- * @return Returns the _userCondition.
- */
- public UserCondition getUserCondition() {
- return _userCondition;
- }
-
- /**
- * @param aUserCondition The _userCondition to set.
- */
- protected void setUserCondition(UserCondition aUserCondition) {
- _userCondition = aUserCondition;
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization.hibernate;
-
-import org.wamblee.usermgt.hibernate.UsermgtHibernateMappingFiles;
-
-/**
- * Mapping files for authorization.
- *
- * @author Erik Brakkee
- */
-public class AuthorizationMappingFiles extends UsermgtHibernateMappingFiles {
-
- public AuthorizationMappingFiles() {
- super(new String[]{ "hbm/AuthorizationRule.hbm.xml", "hbm/UserCondition.hbm.xml",
- "hbm/AuthorizationService.hbm.xml", "hbm/OperationCondition.hbm.xml", "hbm/PathCondition.hbm.xml",
- "hbm/TestAuthorizationRule.hbm.xml" });
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization.hibernate;
-
-import java.util.List;
-
-import org.springframework.orm.hibernate3.HibernateTemplate;
-import org.wamblee.persistence.AbstractPersistent;
-import org.wamblee.persistence.hibernate.HibernateSupport;
-import org.wamblee.security.authorization.AuthorizationRule;
-import org.wamblee.security.authorization.AuthorizationService;
-import org.wamblee.security.authorization.DefaultAuthorizationService;
-import org.wamblee.security.authorization.Operation;
-import org.wamblee.usermgt.UserAccessor;
-
-/**
- * Authorization service with persistent storage.
- * This is a wrapper for {@link org.wamblee.security.authorization.DefaultAuthorizationService}
- * which refreshes the state of the service at certain time intervals.
- *
- * @author Erik Brakkee
- */
-public class PersistentAuthorizationService extends AbstractPersistent
- implements AuthorizationService {
-
- /**
- * Name of query to find the service by name.
- */
- private static final String FIND_QUERY = "findAuthorizationServiceByName";
-
- /**
- * Name of the query parameter for the service name.
- */
- private static final String NAME_PARAM = "name";
-
- /**
- * Authorization service to use.
- */
- private DefaultAuthorizationService _service;
-
- /**
- * Hibernate template to use.
- */
- private HibernateTemplate _template;
-
- /**
- * User accessor.
- */
- private UserAccessor _userAccessor;
-
- /**
- * Name of the service.
- */
- private String _name;
-
- /**
- * Refresh interval in milliseconds.
- */
- private final long _refreshInterval;
-
- /**
- * Last refresh time.
- */
- private long _lastRefreshTime;
-
- /**
- * Constructs the persistent service.
- *
- * @param aName
- * Name of the service.
- * @param aTemplate
- * Hibernate template for hibernate usage.
- * @param aAccessor
- * User accessor.
- * @param aRefresh
- * Whether or not to refresh the state of the service at the
- * start of every operation.
- */
- public PersistentAuthorizationService(String aName,
- HibernateTemplate aTemplate, UserAccessor aAccessor,
- long aRefreshInterval) {
- _template = aTemplate;
- _refreshInterval = aRefreshInterval;
- _lastRefreshTime = System.currentTimeMillis();
- _userAccessor = aAccessor;
- _name = aName;
- }
-
- /**
- * Initialize service if needed.
- */
- private void initialize() {
- if (_service == null) {
- List<DefaultAuthorizationService> result = _template
- .findByNamedQueryAndNamedParam(FIND_QUERY, NAME_PARAM,
- _name);
-
- if (result.size() > 1) {
- throw new IllegalArgumentException(
- "Returned more than one service for name '" + _name
- + "' (" + result.size() + ")");
- }
-
- if (result.size() == 0) {
- _service = new DefaultAuthorizationService(_userAccessor, _name);
- _template.persist(_service);
- } else {
- _service = result.get(0);
- _service.setUserAccessor(_userAccessor);
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationService#isAllowed(java.lang.Object,
- * org.wamblee.security.authorization.Operation)
- */
- public boolean isAllowed(Object aResource, Operation aOperation) {
- initialize();
- refresh();
- return _service.isAllowed(aResource, aOperation);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.AuthorizationService#check(T, org.wamblee.security.authorization.Operation)
- */
- public <T> T check(T aResource, Operation aOperation) {
- initialize();
- refresh();
- return _service.check(aResource, aOperation);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationService#getRules()
- */
- public AuthorizationRule[] getRules() {
- initialize();
- refresh();
- return _service.getRules();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationService#appendRule(org.wamblee.security.authorization.AuthorizationRule)
- */
- public void appendRule(AuthorizationRule aRule) {
- initialize();
- refresh();
- _service.appendRule(aRule);
- save();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationService#removeRule(int)
- */
- public void removeRule(int aIndex) {
- initialize();
- refresh();
- _service.removeRule(aIndex);
- save();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.security.authorization.AuthorizationService#insertRuleAfter(int,
- * org.wamblee.security.authorization.AuthorizationRule)
- */
- public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
- initialize();
- refresh();
- _service.insertRuleAfter(aIndex, aRule);
- save();
- }
-
- /**
- * Refreshes the state of the service through hibernate.
- *
- */
- private synchronized void refresh() {
- long time = System.currentTimeMillis();
- if ( time - _lastRefreshTime > _refreshInterval ) {
- _template.refresh(_service);
- _lastRefreshTime = time;
- }
- }
-
- /**
- * Saves any changes to the service state if necessary.
- */
- private void save() {
- HibernateSupport.merge(_template, _service);
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.io.Serializable;
-
-import org.wamblee.persistence.AbstractPersistent;
-
-/**
- * Represents a group.
- *
- * @author Erik Brakkee
- */
-public class Group extends AbstractPersistent implements Serializable, Comparable {
-
- /**
- * Group name.
- */
- private String _name;
-
- /**
- * Constructs the group.
- * @param aName
- */
- Group(String aName) {
- super();
- _name = aName;
- }
-
- public Group(Group aGroup) {
- super(aGroup);
- _name = aGroup._name;
- }
-
- protected Group() {
- super();
- _name = null;
- }
-
- /**
- * Gets the name of the group.
- * @return Group name.
- */
- public String getName() {
- return _name;
- }
-
- /**
- * Sets the group name.
- * @param aName Group name.
- */
- void setName(String aName) {
- _name = aName;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object aGroup) {
- if ( !( aGroup instanceof Group )) {
- return false;
- }
- return _name.equals(((Group)aGroup)._name);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return _name.hashCode();
- }
-
- /* (non-Javadoc)
- * @see java.lang.Comparable#compareTo(T)
- */
- public int compareTo(Object aGroup) {
- return _name.compareTo(((Group)aGroup)._name);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "Group(pk = " + getPrimaryKey() + ", name=" + _name + ")";
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.io.Serializable;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.wamblee.persistence.AbstractPersistent;
-import org.wamblee.security.encryption.MessageDigester;
-import org.wamblee.usermgt.UserMgtException.Reason;
-
-/**
- * Represents a user.
- * The methods for managing the groups of the user have package scope.
- * Managing the groups of the user should be done through the
- * {@link org.wamblee.usermgt.UserAdministration} interface.
- */
-public class User extends AbstractPersistent implements Serializable, Comparable {
-
- /**
- * User name.
- */
- private String _name;
-
- /**
- * Password.
- */
- private String _password;
-
- /**
- * Groups the user belongs to.
- */
- private Set<Group> _groups;
-
- /**
- * Password validator.
- */
- private NameValidator _passwordValidator;
-
- /**
- * Password encoder.
- */
- private MessageDigester _passwordEncoder;
-
- /**
- * Constructs the user.
- * @param aName User name.
- * @param aPassword Password.
- * @param aGroup Group the user belongs to.
- */
- User(String aName, String aPassword, Group aGroup, NameValidator aPasswordValidator,
- MessageDigester aPasswordEncoder) throws UserMgtException {
- super();
- _name = aName;
- aPasswordValidator.validate(aPassword);
- _password = aPasswordEncoder.hash(aPassword);
- _groups = new TreeSet<Group>();
- _groups.add(aGroup);
- _passwordValidator = aPasswordValidator;
- _passwordEncoder = aPasswordEncoder;
- }
-
- public User(User aUser) {
- super(aUser);
- _name = aUser._name;
- _password = aUser._password;
- _groups = new TreeSet<Group>();
- for (Group group: aUser._groups) {
- _groups.add(new Group(group));
- }
- _passwordValidator = aUser._passwordValidator;
- _passwordEncoder = aUser._passwordEncoder;
- }
-
- User() {
- super();
- _name = null;
- _password = null;
- _groups = null;
- _passwordValidator = null;
- _passwordEncoder = null;
- }
-
- /**
- * Sets the password validator.
- * @param aPasswordValidator Validator.
- */
- public void setPasswordValidator(NameValidator aPasswordValidator) {
- _passwordValidator = aPasswordValidator;
- }
-
- /**
- * Sets the password encoder.
- * @param aPasswordEncoder Encoder.
- */
- public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
- _passwordEncoder = aPasswordEncoder;
- }
-
- /**
- * @return Returns the _password.
- */
- String getPassword() {
- return _password;
- }
-
- /**
- * Checks the password.
- * @param aPassword Password to check.
- * @throws UserMgtException In case the password is incorrect.
- */
- public void checkPassword(String aPassword) throws UserMgtException {
- String encoded = _passwordEncoder.hash(aPassword);
- if ( !_password.equals(encoded) ) {
- throw new UserMgtException(Reason.INVALID_PASSWORD, this);
- }
- }
-
- /**
- * Changes the password.
- * @param aOldPassword Old password.
- * @param aNewPassword New password.
- * @throws UserMgtException In case the old password is incorrect.
- */
- public void changePassword(String aOldPassword, String aNewPassword) throws UserMgtException {
- checkPassword(aOldPassword);
- _passwordValidator.validate(aNewPassword);
- setPassword(aNewPassword);
- }
-
- /**
- * @param aPassword
- * The password to set.
- */
- public void setPassword(String aPassword) throws UserMgtException {
- _passwordValidator.validate(aPassword);
- _password = _passwordEncoder.hash(aPassword);
- }
-
- /**
- * For OR mapping.
- * @return Password.
- */
- protected String getPasswordString() {
- return _password;
- }
-
- /**
- * For OR mapping.
- * @param aPassword Password.
- */
- protected void setPasswordString(String aPassword) {
- _password = aPassword;
- }
-
- /**
- * @return Returns the _user.
- */
- public String getName() {
- return _name;
- }
-
- /**
- * @param aName
- * The username to set.
- */
- void setName(String aName) {
- _name = aName;
- }
-
- /**
- * Gets the groups the user belongs to.
- * @return Groups.
- */
- public Set<Group> getGroups() {
- Set<Group> result = new TreeSet<Group>();
- result.addAll(_groups);
- return result;
- }
-
- /**
- * Checks whether the user belongs to the given group.
- * @param aGroup Group.
- * @return True if the user belongs to the group.
- */
- public boolean isInGroup(Group aGroup) {
- return _groups.contains(aGroup);
- }
-
- /**
- * Checks whether the user belongs to the given group.
- * @param aGroup Group.
- * @return True if the user belongs to the group.
- */
- public boolean isInGroup(String aGroup) {
- return _groups.contains(new Group(aGroup));
- }
-
- /**
- * Gets the group set. For OR mapping.
- * @return set of groups.
- */
- Set<Group> getGroupSet() {
- return _groups;
- }
-
- /**
- * Sets the groups the user belongs to, for OR mapping.
- * @param aGroups Groups.
- */
- void setGroupSet(Set<Group> aGroups) {
- _groups = aGroups;
- }
-
- /**
- * Adds the user to a group.
- * @param aGroup Group to add the user to.
- * @throws UserMgtException In case the user already belongs to the group.
- */
- void addGroup(Group aGroup) throws UserMgtException {
- if (_groups.contains(aGroup)) {
- throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
- }
- _groups.add(aGroup);
- }
-
- /**
- * Removes the user from a group.
- * @param aGroup Group.
- * @throws UserMgtException In case the user does not belong to the group.
- */
- void removeGroup(Group aGroup) throws UserMgtException {
- if (!_groups.contains(aGroup)) {
- throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
- }
- if ( _groups.size() == 1 ) {
- throw new UserMgtException(Reason.USER_MUST_BE_IN_A_GROUP, this, aGroup);
- }
- _groups.remove(aGroup);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object aUser) {
- if ( !(aUser instanceof User)) {
- return false;
- }
- User user = (User)aUser;
- return _name.equals(user._name);
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return _name.hashCode();
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- String result = "User(name=" + _name + ", password=" + _password;
- for (Group group: _groups) {
- result += ", group=" + group;
- }
- return result + ")";
- }
-
- /* (non-Javadoc)
- * @see java.lang.Comparable#compareTo(T)
- */
- public int compareTo(Object aUser) {
- return _name.compareTo(((User)aUser)._name);
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.util.Set;
-
-/**
- * Interface for user administration. Manages the users and groups.
- *
- * @author Erik Brakkee
- */
-public interface UserAdministration {
-
- /**
- * Creates a new user.
- * @param aUser Username.
- * @param aPassword Password.
- * @param aGroup Group.
- * @return User.
- * @throws UserMgtException In case there is a conflict with an existing user.
- */
- User createUser(String aUser, String aPassword, Group aGroup) throws UserMgtException;
-
- /**
- * Creates a new group.
- * @param aName Group name.
- * @return Group
- * @throws UserMgtException In case there is a conflict with an existing group.
- */
- Group createGroup(String aName) throws UserMgtException;
-
- /**
- * @return Number of users.
- */
- int getUserCount();
-
- /**
- * @return Number of groups.
- */
- int getGroupCount();
-
- /**
- * Must be called when the user is modified.
- * @param aUser User.
- */
- void userModified(User aUser);
-
- /**
- * Must be called when the group is modified.
- * @param aGroup Group.
- */
- void groupModified(Group aGroup);
-
- /**
- * Gets the user for a given name.
- * @param aName User name.
- * @return User or null if not found.
- */
- User getUser(String aName);
-
- /**
- * Gets the group for a given group name.
- * @param aName Group name.
- * @return Group or null if not found.
- */
- Group getGroup(String aName);
-
- /**
- * Get the users.
- * @return All known users.
- */
- Set<User> getUsers();
-
- /**
- * Gets the users for a given group.
- * @param aGroup Group.
- * @return Set of users (always non-null).
- */
- Set<User> getUsers(Group aGroup);
-
- /**
- * Gets all known groups.
- * @return Groups.
- */
- Set<Group> getGroups();
-
- /**
- * Renames a user.
- * @param aUser User object for which user name must be changed.
- * @param aUserName New user name.
- * @throws UserMgtException In case the user is not known or the new user
- * name is already in use by another user.
- */
- void renameUser(User aUser, String aUserName) throws UserMgtException;
-
- /**
- * Renames a group.
- * @param aGroup Group to rename.
- * @param aGroupName New name for the group.
- * @throws UserMgtException In case the new group name is already used by
- * another group of if the existing group is unknown.
- */
- void renameGroup(Group aGroup, String aGroupName) throws UserMgtException;
-
- /**
- * Removes the user.
- * @param aUser User to remove.
- * @throws UserMgtException In case the user does not exist.
- */
- void removeUser(User aUser) throws UserMgtException;
-
- /**
- * Removes the group.
- * @param aGroup Group to remove.
- * @throws UserMgtException In case there are still users that are in the given group.
- */
- void removeGroup(Group aGroup) throws UserMgtException;
-
- /**
- * Adds a user to a group.
- * @param aUser User.
- * @param aGroup Group.
- * @throws UserMgtException In case the user or group or not known or if the user
- * is already part of the group.
- */
- void addUserToGroup(User aUser, Group aGroup) throws UserMgtException;
-
- /**
- * Removes a user from a group.
- * @param aUser User
- * @param aGroup Group
- * @throws UserMgtException In case the user or group are unknown or if the user
- * is not part of the group.
- */
- void removeUserFromGroup(User aUser, Group aGroup) throws UserMgtException;
-}
-
+++ /dev/null
-/*
- * Copyright 2008 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import net.sf.ehcache.Ehcache;
-
-import org.hibernate.SessionFactory;
-import org.wamblee.cache.EhCache;
-import org.wamblee.system.core.DefaultProvidedInterface;
-import org.wamblee.system.core.DefaultRequiredInterface;
-import org.wamblee.system.core.ProvidedInterface;
-import org.wamblee.system.core.RequiredInterface;
-import org.wamblee.system.spring.SpringComponent;
-
-public class UserGroupRepositoryComponent extends SpringComponent {
-
- public UserGroupRepositoryComponent(String aName) {
- super(aName, new String[] { "spring/org.wamblee.security.usermgt-repositories.xml" } ,
- createProvided(), createRequired());
-
- }
-
- private static Map<RequiredInterface, String> createRequired() {
- Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
- required.put(new DefaultRequiredInterface("sessionFactory", SessionFactory.class), "sessionFactory");
- return required;
- }
-
- private static Map<String, ProvidedInterface> createProvided() {
- Map<String,ProvidedInterface> provided = new HashMap<String,ProvidedInterface>();
- provided.put("userCache", new DefaultProvidedInterface("cache", EhCache.class));
- provided.put(UserSet.class.getName(), new DefaultProvidedInterface("userset", UserSet.class));
- provided.put(GroupSet.class.getName(), new DefaultProvidedInterface("groupset", GroupSet.class));
- return provided;
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.util.Set;
-
-/**
- * Represents a set of users.
- * Typical implementations would be an implementation based on a static configuration file or
- * an implementation backed by a database.
- *
- * @author Erik Brakkee
- */
-public interface UserSet {
-
- /**
- * Creates a user.
- * @param aUsername User name.
- * @param aPassword Password.
- * @param aGroup Group.
- * @return New user.
- * @throws UserMgtException In case the user cannot be created.
- */
- User createUser(String aUsername, String aPassword, Group aGroup) throws UserMgtException;
-
- /**
- * Must be called whenever a user object has been modified to notify the
- * user set.
- * @param aUser Modified user.
- */
- void userModified(User aUser);
-
- /**
- * Finds user.
- * @param aName Username.
- * @return User or null if not found.
- */
- User find(String aName);
-
- /**
- * Checks if a user exists.
- * @param aUser User.
- * @return True iff the user exists.
- */
- boolean contains(User aUser);
-
- /**
- * Adds a user. If the user already exists, the user details are updated with that
- * of the specified user object.
- * @param aUser User to add.
- */
- boolean add(User aUser);
-
- /**
- * Removes a user. If the user does not exist, nothing happens.
- * @param aUser
- */
- boolean remove(User aUser);
-
- /**
- * Lists the current users.
- * @return Users.
- */
- Set<User> list();
-
- /**
- * Lists the users belonging to a particular group.
- * @param aGroup Group.
- * @return Groups.
- */
- Set<User> list(Group aGroup);
-
- /**
- *
- * @return The number of users.
- */
- int size();
-}
+++ /dev/null
-/*
- * Copyright 2008 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.io.IOException;
-
-import javax.sql.DataSource;
-
-import org.springframework.orm.hibernate3.HibernateTemplate;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.wamblee.cache.EhCache;
-import org.wamblee.security.authorization.AuthorizationService;
-import org.wamblee.security.authorization.hibernate.AuthorizationMappingFiles;
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.components.ORMappingConfig;
-import org.wamblee.system.core.Component;
-import org.wamblee.system.core.DefaultProvidedInterface;
-import org.wamblee.system.core.DefaultRequiredInterface;
-import org.wamblee.system.core.ProvidedInterface;
-import org.wamblee.system.core.Scope;
-import org.wamblee.system.spring.component.HibernateComponent;
-import org.wamblee.usermgt.UserAccessor;
-import org.wamblee.usermgt.UserAdministration;
-import org.wamblee.usermgt.UserGroupRepositoryComponent;
-
-public class AuthorizationComponent extends DefaultContainer {
-
- private ProvidedInterface TRANSACTION_MGR = new DefaultProvidedInterface(
- "transactionManager", PlatformTransactionManager.class);
- private ProvidedInterface HIBERNATE_TEMPLATE = new DefaultProvidedInterface(
- "hibernateTemplate", HibernateTemplate.class);
- private ProvidedInterface AUTHORIZATION_SERVICE = new DefaultProvidedInterface(
- "authorizationService", AuthorizationService.class);
-
- public AuthorizationComponent(String aName, boolean aExposeInternals)
- throws IOException {
- super(aName);
-
- ObjectConfiguration authConfig = new ObjectConfiguration(AuthorizationMappingFiles.class);
- authConfig.getSetterConfig().initAllSetters();
- addComponent("mappingFiles", new AuthorizationMappingFiles(), authConfig);
-
- Component<?> hibernate = new HibernateComponent("hibernate");
- addComponent(hibernate);
-
- Component<?> authorization = new AuthorizationLightComponent("authorization");
- addComponent(authorization);
-
- addRequiredInterface(new DefaultRequiredInterface("datasource", DataSource.class));
- addRequiredInterface(new DefaultRequiredInterface("userAccessor",
- UserAccessor.class));
- addRequiredInterface(new DefaultRequiredInterface("ormconfig", ORMappingConfig.class));
-
- if (aExposeInternals) {
- addProvidedInterface(TRANSACTION_MGR);
- addProvidedInterface(HIBERNATE_TEMPLATE);
- }
- addProvidedInterface(AUTHORIZATION_SERVICE);
- }
-}
+++ /dev/null
-/*
- * Copyright 2008 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.orm.hibernate3.HibernateTemplate;
-import org.wamblee.security.authorization.AuthorizationService;
-import org.wamblee.system.core.DefaultProvidedInterface;
-import org.wamblee.system.core.DefaultRequiredInterface;
-import org.wamblee.system.core.ProvidedInterface;
-import org.wamblee.system.core.RequiredInterface;
-import org.wamblee.system.spring.SpringComponent;
-import org.wamblee.usermgt.GroupSet;
-import org.wamblee.usermgt.UserAccessor;
-import org.wamblee.usermgt.UserAdministration;
-import org.wamblee.usermgt.UserSet;
-
-/**
- * Light version of the user administration component that requires external
- * datasource, and userset and group set components, as well as an external
- * hibernate session factory.
- *
- * @author Erik Brakkee
- *
- */
-public class AuthorizationLightComponent extends SpringComponent {
-
- public AuthorizationLightComponent(String aName) {
- super(
- aName,
- new String[] { "spring/org.wamblee.security.authorization.xml" },
- createProvided(), createRequired());
- }
-
- private static Map<RequiredInterface, String> createRequired() {
- Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
- required.put(new DefaultRequiredInterface("userArccessor",
- UserAccessor.class), UserAccessor.class.getName());
- required.put(new DefaultRequiredInterface("hibernateTemplate",
- HibernateTemplate.class), HibernateTemplate.class.getName());
- return required;
- }
-
- private static Map<String, ProvidedInterface> createProvided() {
- Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
- provided.put(AuthorizationService.class.getName(),
- new DefaultProvidedInterface(AuthorizationService.class
- .getName(), AuthorizationService.class));
- return provided;
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.wamblee.persistence.hibernate.HibernateSupport;
-import org.wamblee.usermgt.Group;
-import org.wamblee.usermgt.GroupSet;
-
-/**
- * Set of groups backed by the database.
- *
- * @author Erik Brakkee
- */
-public class HibernateGroupSet extends HibernateSupport implements GroupSet {
-
-
- private static final String QUERY_FIND_BY_NAME = "findGroupByName";
-
- private static final String PARAM_NAME = "name";
-
- private static final String QUERY_COUNT_GROUPS = "countGroups";
-
- public HibernateGroupSet() {
- // Empty
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#groupModified(org.wamblee.usermgt.Group)
- */
- public void groupModified(Group aGroup) {
- assert aGroup.getPrimaryKey() != null;
- super.merge(aGroup);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#find(java.lang.String)
- */
- public Group find(String aName) {
- List list = getHibernateTemplate().findByNamedQueryAndNamedParam(QUERY_FIND_BY_NAME, PARAM_NAME, aName);
- if ( list.size() > 1 ) {
- throw new RuntimeException("More than one group with the same name '" + aName + "'");
- }
- if ( list.size() == 0 ) {
- return null;
- }
- return new Group((Group)list.get(0));
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#contains(org.wamblee.usermgt.Group)
- */
- public boolean contains(Group aGroup) {
- return find(aGroup.getName()) != null;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#add(org.wamblee.usermgt.Group)
- */
- public boolean add(Group aGroup) {
- assert aGroup.getPrimaryKey() == null;
- if ( contains(aGroup) ) {
- return false;
- }
- super.merge(aGroup);
- return true;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#remove(org.wamblee.usermgt.Group)
- */
- public boolean remove(Group aGroup) {
- assert aGroup.getPrimaryKey() != null;
- if ( !contains(aGroup)) {
- return false;
- }
- Group group = (Group) getHibernateTemplate().merge(aGroup);
- getHibernateTemplate().delete(group);
- aGroup.setPrimaryKey(null);
- aGroup.setPersistedVersion(-1);
- return true;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#list()
- */
- public Set<Group> list() {
- Set<Group> groups = new TreeSet<Group>();
- List<Group> list = getHibernateTemplate().loadAll(Group.class);
- for (Group group: list) {
- groups.add(new Group(group));
- }
- return groups;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.GroupSet#size()
- */
- public int size() {
- Long result = (Long) getHibernateTemplate().findByNamedQuery(QUERY_COUNT_GROUPS).get(0);
- return result.intValue();
- }
-}
+++ /dev/null
-/*
- * Copyright 2008 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.io.IOException;
-
-import javax.sql.DataSource;
-
-import org.springframework.orm.hibernate3.HibernateTemplate;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.wamblee.cache.EhCache;
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.components.ORMappingConfig;
-import org.wamblee.system.core.Component;
-import org.wamblee.system.core.DefaultProvidedInterface;
-import org.wamblee.system.core.DefaultRequiredInterface;
-import org.wamblee.system.core.ProvidedInterface;
-import org.wamblee.system.core.Scope;
-import org.wamblee.system.spring.component.HibernateComponent;
-import org.wamblee.usermgt.UserAdministration;
-import org.wamblee.usermgt.UserGroupRepositoryComponent;
-
-public class UserAdministrationComponent extends DefaultContainer {
-
- private ProvidedInterface TRANSACTION_MGR = new DefaultProvidedInterface(
- "transactionManager", PlatformTransactionManager.class);
- private ProvidedInterface USER_CACHE = new DefaultProvidedInterface(
- "userCache", EhCache.class);
- private ProvidedInterface HIBERNATE_TEMPLATE = new DefaultProvidedInterface(
- "hibernateTemplate", HibernateTemplate.class);
- private ProvidedInterface USER_MGT = new DefaultProvidedInterface(
- "usermgt", UserAdministration.class);
-
- public UserAdministrationComponent(String aName, boolean aExposeInternals)
- throws IOException {
- super(aName);
-
- ObjectConfiguration mappingFilesConfig = new ObjectConfiguration(UsermgtHibernateMappingFiles.class);
- mappingFilesConfig.getSetterConfig().initAllSetters();
- addComponent("mappingFiles", new UsermgtHibernateMappingFiles(), mappingFilesConfig);
-
- Component<?> _hibernate = new HibernateComponent("hibernate");
- addComponent(_hibernate);
-
- Component<?> _repository = new UserGroupRepositoryComponent("usersgroups");
- addComponent(_repository);
-
- Component<?> _usermgt = new UserAdministrationLightComponent("usermgtlight");
- addComponent(_usermgt);
-
- addRequiredInterface(new DefaultRequiredInterface("datasource",
- DataSource.class));
- addRequiredInterface(new DefaultRequiredInterface("ormconfig", ORMappingConfig.class));
-
- if (aExposeInternals) {
- addProvidedInterface(TRANSACTION_MGR);
- addProvidedInterface(USER_CACHE);
- addProvidedInterface(HIBERNATE_TEMPLATE);
- }
- addProvidedInterface(USER_MGT);
- }
-}
+++ /dev/null
-/*
- * Copyright 2008 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.wamblee.system.core.DefaultProvidedInterface;
-import org.wamblee.system.core.DefaultRequiredInterface;
-import org.wamblee.system.core.ProvidedInterface;
-import org.wamblee.system.core.RequiredInterface;
-import org.wamblee.system.spring.SpringComponent;
-import org.wamblee.usermgt.GroupSet;
-import org.wamblee.usermgt.UserAdministration;
-import org.wamblee.usermgt.UserSet;
-
-/**
- * Light version of the user administration component that requires external
- * datasource, and userset and group set components, as well as an external
- * hibernate session factory.
- * @author Erik Brakkee
- *
- */
-public class UserAdministrationLightComponent extends SpringComponent {
-
- public UserAdministrationLightComponent(String aName) {
- super(aName, new String[] { "spring/org.wamblee.security.usermgt.xml" },
- createProvided(), createRequired() );
- }
-
- private static Map<RequiredInterface, String> createRequired() {
- Map<RequiredInterface, String> required = new HashMap<RequiredInterface,String>();
- required.put(new DefaultRequiredInterface("userSet", UserSet.class), UserSet.class.getName());
- required.put(new DefaultRequiredInterface("groupSet", GroupSet.class), GroupSet.class.getName());
- return required;
- }
-
- private static Map<String, ProvidedInterface> createProvided() {
- Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
- provided.put(UserAdministration.class.getName(), new DefaultProvidedInterface("org.wamblee.usermgt.UserAdministration",
- UserAdministration.class));
- return provided;
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.util.Collections;
-
-import org.wamblee.persistence.hibernate.HibernateMappingFiles;
-
-/**
- * Hibernate mapping files for user management.
- *
- * @author Erik Brakkee
- */
-public class UsermgtHibernateMappingFiles extends HibernateMappingFiles {
-
- public UsermgtHibernateMappingFiles() {
- super(new String[] {
- "hbm/Group.hbm.xml", "hbm/User.hbm.xml"
- });
- }
-
- public UsermgtHibernateMappingFiles(String[] aFiles) {
- this();
- Collections.addAll(this, aFiles);
- }
-}
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-
- <hibernate-mapping>
- <subclass name="org.wamblee.photos.authorizationrules.PageAuthorizationRule"
- extends="org.wamblee.security.authorization.UrlAuthorizationRule"
- discriminator-value="PAGE"
- lazy="false"/>
-
- </hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-
- <hibernate-mapping>
- <subclass name="org.wamblee.photos.authorizationrules.PhotoAuthorizationRule"
- extends="org.wamblee.security.authorization.AuthorizationRule"
- discriminator-value="PHOTOS"
- lazy="false"/>
-
- </hibernate-mapping>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
-import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
-import junit.framework.TestCase;
-
-import org.wamblee.usermgt.UserAccessor;
-
-/**
- * Tests the authorization service.
- *
- * @author Erik Brakkee
- */
-public class AuthorizationServiceTest extends TestCase {
-
- private AuthorizationRule _rule1;
- private AuthorizationRule _rule2;
- private AuthorizationRule _rule3;
- private AuthorizationService _service;
-
- protected AuthorizationService getService() {
- return _service;
- }
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- _rule1 = createRule(GRANTED, "users", "/oni/", AllOperation.class);
- _rule2 = createRule(DENIED, "users", "/abc/", ReadOperation.class);
- _rule3 = createRule(GRANTED, "users", "/abc/", AllOperation.class);
-
- _service = createService();
- _service.appendRule(_rule1);
- _service.appendRule(_rule2);
- _service.appendRule(_rule3);
- }
-
- protected void resetTestRules() {
- ((TestAuthorizationRule)_rule1).reset();
- ((TestAuthorizationRule)_rule2).reset();
- ((TestAuthorizationRule)_rule3).reset();
- }
-
- protected UserAccessor createUserAccessor() {
- return new TestUserAccessor();
- }
-
- /**
- * Creates an authorization service with some rules for testing. .
- * @return Authorization service.
- */
- protected AuthorizationService createService() {
- DefaultAuthorizationService service = new DefaultAuthorizationService() ;
- service.setUserAccessor(createUserAccessor());
- return service;
- }
-
- protected AuthorizationRule createRule(AuthorizationResult aResult, String aGroup, String aPath, Class<? extends Operation> aOperation) {
- return new TestAuthorizationRule(aResult, aGroup, aPath, aOperation);
- }
-
- protected void checkMatchCount(int aCount, AuthorizationRule aRule) {
- assertEquals( aCount, ((TestAuthorizationRule)aRule).getMatchCount());
- }
-
- protected Object createResource(String aPath) {
- return new TestResource(aPath);
- }
-
- protected void checkRuleCount(int aCount) {
- // Empty
- }
-
- /**
- * Several checks to verify the outcome of matching against the first rule.
- *
- */
- public void testFirstRuleGrants() {
- assertTrue( _service.isAllowed(createResource("/oni/xyz.jpg"), new ReadOperation()));
- checkMatchCount(1, _rule1);
- assertTrue(_service.isAllowed(createResource("/oni/xyz.jpg"), new WriteOperation()));
- checkMatchCount(2, _rule1);
- assertTrue(_service.isAllowed(createResource("/oni/xyz.jpg"), new DeleteOperation()));
- checkMatchCount(3, _rule1);
- assertTrue(_service.isAllowed(createResource("/oni/xyz.jpg"), new CreateOperation()));
- checkMatchCount(4, _rule1);
- checkMatchCount(0, _rule2);
- checkMatchCount(0, _rule3);
- }
-
- /**
- * Verify that a match with the second rule leads to a denial of authorization.
- *
- */
- public void testSecondRuleDenies() {
- assertFalse(_service.isAllowed(createResource("/abc/xyz.jpg"), new ReadOperation()));
- checkMatchCount(0, _rule1);
- checkMatchCount(1, _rule2);
- checkMatchCount(0, _rule3);
- }
-
- /**
- * Verifies that the third rule is used when appropriate and that it grants access.
- *
- */
- public void testThirdRuleGrants() {
- assertTrue(_service.isAllowed(createResource("/abc/xyz.jpg"), new WriteOperation()));
- checkMatchCount(0, _rule1);
- checkMatchCount(0, _rule2);
- checkMatchCount(1, _rule3);
- }
-
- /**
- * Removes a rule and checks it is removed.
- *
- */
- public void testRemoveRule() {
- checkRuleCount(3);
- assertTrue(_service.isAllowed(createResource("/abc/xyz.jpg"), new WriteOperation()));
- _service.removeRule(2);
- assertFalse(_service.isAllowed(createResource("/abc/xyz.jpg"), new WriteOperation()));
- checkRuleCount(2);
- }
-
- /**
- * Inserts a rule and checks it is inserted.
- *
- */
- public void testInsertRule() {
- checkRuleCount(3);
- assertFalse(_service.isAllowed(createResource("/janse/xyz.jpg"), new WriteOperation()));
- _service.appendRule(createRule(GRANTED, "users", "/janse/", WriteOperation.class));
- assertTrue(_service.isAllowed(createResource("/janse/xyz.jpg"), new WriteOperation()));
- checkRuleCount(4);
-
- }
-
- /**
- * Gets the rules. Verifies that all rules are obtained.
- *
- */
- public void testGetRules() {
- AuthorizationRule[] rules = _service.getRules();
- assertEquals(3, rules.length);
- }
-
- /**
- * Verifies that when no rules match, access is denied.
- *
- */
- public void testNoRulesSupportResource() {
- assertFalse(_service.isAllowed(createResource("/xyxyxyxy"), new ReadOperation()));
- checkMatchCount(0, _rule1);
- checkMatchCount(0, _rule2);
- checkMatchCount(0, _rule3);
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import junit.framework.TestCase;
-
-/**
- * Test of the operation registry.
- *
- * @author Erik Brakkee
- */
-public class DefaultOperationRegistryTest extends TestCase {
-
- private OperationRegistry _registry;
-
- /* (non-Javadoc)
- * @see junit.framework.TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception {
-
- _registry = new DefaultOperationRegistry(new Operation[] {
- new AllOperation(),
- new ReadOperation(),
- new WriteOperation(),
- new DeleteOperation(),
- new CreateOperation()
- });
- }
-
- /**
- * Tests encoding and decoding of no operations.
- *
- */
- public void testEncodeDecodeNooperations() {
- assertEquals("", _registry.encode(new Operation[0]));
- assertEquals(0, _registry.decode(Object.class, "").length);
- }
-
- /**
- * Verifies that encoding of operations into a string works.
- *
- */
- public void testEncode() {
- assertEquals("read,write", _registry.encode(new Operation[] { new ReadOperation(), new WriteOperation() }));
- }
-
- /**
- * Verifies that decoding of operation from a string works.
- *
- */
- public void testDecode() {
- Operation[] operations = _registry.decode(Object.class, "read,write");
- assertTrue( operations[0] instanceof ReadOperation);
- assertTrue( operations[1] instanceof WriteOperation);
- }
-
- /**
- * Verifies that an IllegalArgumentException occurs when attempting to decode
- * an operation that is not known.
- *
- */
- public void testDecodeUnknownOperation() {
- try {
- _registry.decode(Object.class, "bla");
- fail();
- } catch (IllegalArgumentException e) {
- // ok
- }
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization;
-
-import static org.wamblee.security.authorization.AuthorizationResult.DENIED;
-import static org.wamblee.security.authorization.AuthorizationResult.GRANTED;
-
-import org.wamblee.usermgt.User;
-
-/**
- * Test authorization rule that also counts the number of times the rule matches.
- *
- * @author Erik Brakkee
- */
-public class TestAuthorizationRule extends UrlAuthorizationRule {
-
- /**
- * Counts the number of matches.
- */
- private int _matches = 0;
-
- public TestAuthorizationRule( AuthorizationResult aResult, String aGroup,
- String aPath, Class<? extends Operation> aOperation) {
- super(aResult, new GroupUserCondition(aGroup),
- new StartsWithPathCondition(aPath), TestResource.class, new IsaOperationCondition(aOperation));
- }
-
- protected TestAuthorizationRule() {
- super();
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.UrlAuthorizationRule#getPath(java.lang.Object)
- */
- @Override
- protected String getResourcePath(Object aResource) {
- return ((TestResource)aResource).getPath();
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.security.authorization.UrlAuthorizationRule#isAllowed(java.lang.Object, org.wamblee.security.authorization.Operation, org.wamblee.usermgt.UserAccessor)
- */
- @Override
- public AuthorizationResult isAllowed(Object aResource, Operation anOperation, User aUser) {
-
- AuthorizationResult result = super.isAllowed(aResource, anOperation, aUser);
- if ( result.equals(GRANTED) || result.equals(DENIED)) {
- _matches++;
- }
- return result;
- }
-
- public int getMatchCount() {
- return _matches;
- }
-
- public void reset() {
- _matches = 0;
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.security.authorization.hibernate;
-
-import java.sql.SQLException;
-
-import org.apache.log4j.Logger;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.dialect.MySQL5Dialect;
-import org.hibernate.dialect.MySQL5InnoDBDialect;
-import org.hibernate.tool.hbm2ddl.SchemaExport;
-import org.springframework.orm.hibernate3.HibernateTemplate;
-import org.wamblee.general.BeanKernel;
-import org.wamblee.security.authorization.AuthorizationService;
-import org.wamblee.security.authorization.AuthorizationServiceTest;
-import org.wamblee.security.authorization.TestUserAccessor;
-import org.wamblee.system.adapters.ClassConfiguration;
-import org.wamblee.system.adapters.ClassConfigurationTest;
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.components.DatabaseComponentFactory;
-import org.wamblee.system.core.Scope;
-import org.wamblee.system.spring.component.DatabaseTesterComponent;
-import org.wamblee.system.spring.component.DatasourceComponent;
-import org.wamblee.usermgt.UserAccessor;
-import org.wamblee.usermgt.hibernate.AuthorizationComponent;
-import org.wamblee.usermgt.hibernate.HibernateUserAdministrationTest;
-import org.wamblee.usermgt.hibernate.UserAdministrationComponent;
-
-/**
- * Unit test for the persistent authorization service.
- *
- * @author Erik Brakkee
- */
-public class PersistentAuthorizationServiceTest extends
- AuthorizationServiceTest {
-
- private static final Logger LOGGER = Logger
- .getLogger(PersistentAuthorizationServiceTest.class);
-
- private static final String SERVICE_TABLE = "AUTHORIZATION_SERVICE";
- private static final String RULES_TABLE = "AUTHORIZATION_RULES";
- private static final String SERVICE_RULES_TABLE = "AUTHORIZATION_SERVICE_RULES";
- private static final String OPERATIONCOND_TABLE = "OPERATION_CONDITIONS";
- private static final String PATHCOND_TABLE = "PATH_CONDITIONS";
- private static final String USERCOND_TABLE = "USER_CONDITIONS";
-
- private DefaultContainer _container;
- private Scope _scope;
-
- private DatabaseTesterComponent _databaseTester;
- private UserAccessor _userAccessor;
- private HibernateTemplate _hibernateTemplate;
- private AuthorizationService _authorizationService;
-
- @Override
- protected void setUp() throws Exception {
-
- _container = new DefaultContainer("top");
- DatabaseComponentFactory.addDatabaseConfig(_container);
- _container.addComponent(new DatasourceComponent("datasource"));
- ClassConfiguration useraccessorConfig = new ClassConfiguration(
- TestUserAccessor.class);
- useraccessorConfig.getObjectConfig().getSetterConfig().initAllSetters();
- _container.addComponent("userAccessor", useraccessorConfig);
- _container.addComponent(new AuthorizationComponent("authorization",
- true));
-
- ClassConfiguration dbtesterConfig = new ClassConfiguration(
- DatabaseTesterComponent.class);
- dbtesterConfig.getObjectConfig().getSetterConfig().initAllSetters();
- _container.addComponent("databaseTester", dbtesterConfig);
-
- ObjectConfiguration config = new ObjectConfiguration(
- PersistentAuthorizationServiceTest.class);
- config.getSetterConfig().clear().add("setUserAccessor").add(
- "setDatabaseTester").add("setHibernateTemplate").add(
- "setAuthorizationService");
- _container.addComponent("testcase", this, config);
-
- _scope = _container.start();
-
- _databaseTester.cleanDatabase();
-
- super.setUp();
- }
-
- public void setDatabaseTester(DatabaseTesterComponent aDatabaseTester) {
- _databaseTester = aDatabaseTester;
- }
-
- public void setUserAccessor(UserAccessor aUserAccessor) {
- _userAccessor = aUserAccessor;
- }
-
- public void setHibernateTemplate(HibernateTemplate aHibernateTemplate) {
- _hibernateTemplate = aHibernateTemplate;
- }
-
- public void setAuthorizationService(
- AuthorizationService aAuthorizationService) {
- _authorizationService = aAuthorizationService;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.wamblee.security.authorization.AuthorizationServiceTest#createService
- * ()
- */
- @Override
- protected AuthorizationService createService() {
- PersistentAuthorizationService service = new PersistentAuthorizationService(
- "DEFAULT", _hibernateTemplate, createUserAccessor(), 10000);
- return service;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.wamblee.security.authorization.AuthorizationServiceTest#checkRuleCount
- * (int)
- */
- @Override
- protected void checkRuleCount(int aCount) {
- try {
- assertEquals(1, _databaseTester.getTableSize(SERVICE_TABLE));
- assertEquals(aCount, _databaseTester.getTableSize(RULES_TABLE));
- assertEquals(aCount, _databaseTester
- .getTableSize(SERVICE_RULES_TABLE));
- assertEquals(aCount, _databaseTester.getTableSize(USERCOND_TABLE));
- assertEquals(aCount, _databaseTester.getTableSize(PATHCOND_TABLE));
- assertEquals(aCount, _databaseTester
- .getTableSize(OPERATIONCOND_TABLE));
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
-
- }
-
- public void testSchemaExport() {
- Configuration config = new Configuration();
- for (String mappingFile: new AuthorizationMappingFiles()) {
- config.addResource(mappingFile);
- }
- config.setProperty("hibernate.dialect", MySQL5InnoDBDialect.class.getName());
- SchemaExport exporter = new SchemaExport(config);
- exporter.setOutputFile("target/mysql5.schema.sql");
- exporter.create(true,false);
- }
-
- public void testPerformance() {
-
- PersistentAuthorizationService service = (PersistentAuthorizationService) getService();
-
- int n = 1000;
- long time = System.currentTimeMillis();
- for (int i = 0; i < n; i++) {
- testFirstRuleGrants();
- resetTestRules();
- testSecondRuleDenies();
- resetTestRules();
- testThirdRuleGrants();
- resetTestRules();
- testNoRulesSupportResource();
- }
- LOGGER.info("Executed " + 4 * n + " authorization checks in "
- + (float) (System.currentTimeMillis() - time) / (float) 1000
- + " seconds.");
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.sql.SQLException;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-/**
- * Tests the inmemory group set. Intended to be subclassed for other
- * implementations of group set.
- */
-public class InMemoryGroupSetTest extends TestCase {
-
- protected GroupSet _groups;
-
- /**
- * This method must be overriden in subclasses.
- * @return New group set object.
- */
- protected GroupSet createGroupSet() {
- return new InMemoryGroupSet();
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.test.SpringTestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- _groups = createGroupSet();
- checkGroupCount(0);
- }
-
-
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aGroup Group to check for existence.
- */
- protected void checkGroupExists(String aGroup) throws SQLException {
- // Empty
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aGroup Group to check for non-existence.
- */
- protected void checkGroupNotExists(String aGroup) throws SQLException {
- // Empty
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aSize Expected number of groups.
- */
- protected void checkGroupCount(int aSize) throws SQLException {
- assertEquals(aSize, _groups.size());
- }
-
- /**
- * Adds a group and verifies that the group is added using
- * find(), list(), and contains().
- *
- */
- public void testAdd() throws SQLException {
- Group group = new Group("group1");
- assertTrue( _groups.add(group) );
- checkGroupExists(group.getName());
- checkGroupCount(1);
- Group group2 = _groups.find("group1");
- assertNotNull(group2);
- assertEquals(group.getName(), group2.getName());
- Set<Group> set = _groups.list();
- assertEquals(1, set.size());
- assertTrue(set.contains(group));
- }
-
- /**
- * Tries to find a non-existing group. Verifies that null is
- * returned.
- *
- */
- public void testFindUnknownGroup() throws SQLException {
- Group group1 = new Group("group1");
- Group group2 = new Group("group2");
- _groups.add(group1);
- _groups.add(group2);
- checkGroupExists(group1.getName());
- checkGroupExists(group2.getName());
-
- assertNull( _groups.find("group3") );
- checkGroupNotExists("group3");
- }
-
- /**
- * Adds duplicate group. Verifies that the existing group is left untouched.
- */
- public void testAddDuplicateGroup() throws SQLException {
- Group group1 = new Group("group1");
- _groups.add(group1);
-
- assertEquals(1, _groups.list().size());
- assertTrue(_groups.contains(group1));
- group1 = new Group("group1");
- assertFalse(_groups.add(group1));
- assertEquals(1, _groups.list().size());
-
- checkGroupExists(group1.getName());
- checkGroupCount(1);
- }
-
- /**
- * Removes a group. Verifies that the group is
- * removed and the return value is true.
- *
- */
- public void testRemoveGroup() throws SQLException {
- Group group1 = new Group("group1");
- _groups.add(group1);
- assertTrue(_groups.contains(group1));
- checkGroupCount(1);
-
- assertTrue(_groups.remove(group1));
- assertFalse(_groups.contains(group1));
- assertNull(_groups.find(group1.getName()));
- assertEquals(0, _groups.list().size());
- checkGroupCount(0);
- }
-
- /**
- * Removes a non-existing group. Verifies that no groups are
- * removed an that the return value is true.
- *
- */
- public void testRemoveNonExistingGroup() throws SQLException {
- Group group1 = new Group("group1");
- _groups.add(group1);
- checkGroupCount(1);
- Group nonExistingGroup = new Group("group2");
- nonExistingGroup.setPrimaryKey(new Long(1000));
- nonExistingGroup.setPersistedVersion(1000);
- assertFalse(_groups.remove(nonExistingGroup));
- assertTrue(_groups.contains(group1));
- assertEquals(1, _groups.list().size());
- checkGroupCount(1);
- }
-
- /**
- * Adds a number of groups to the set and verifies that list()
- * returns them all.
- *
- */
- public void testList() throws SQLException {
- Group group1 = new Group("group1");
- Group group2 = new Group("group2");
- Group group3 = new Group("group3");
- assertTrue(_groups.add(group1));
- assertTrue(_groups.add(group2));
- assertTrue(_groups.add(group3));
-
- checkGroupExists(group1.getName());
- checkGroupExists(group2.getName());
- checkGroupExists(group3.getName());
-
- Set<Group> set = _groups.list();
- assertTrue(set.contains(group1));
- assertTrue(set.contains(group2));
- assertTrue(set.contains(group3));
-
- checkGroupCount(3);
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt;
-
-import java.sql.SQLException;
-import java.util.Set;
-
-import junit.framework.TestCase;
-
-import org.wamblee.security.encryption.Md5HexMessageDigester;
-import org.wamblee.usermgt.UserMgtException.Reason;
-
-/**
- * Tests the inmemory user set. Intended to be subclassed for other
- * implementations of user set.
- */
-public class InMemoryUserSetTest extends TestCase {
-
- protected static final String PASSWORD = "abc123";
-
- private UserSet _users;
- private GroupSet _groups;
-
- private Group _group;
-
- /**
- * This method must be overriden in subclasses.
- * @return New user set object.
- */
- protected UserSet createUserSet() {
- return new InMemoryUserSet( new RegexpNameValidator(RegexpNameValidator.PASSWORD_PATTERN, Reason.INVALID_PASSWORD, "Password must contain at least 6 characters"),
- new Md5HexMessageDigester());
- }
-
- /**
- * This method must be overriden in subclasses.
- * @return New group set object.
- */
- protected GroupSet createGroupSet() {
- return new InMemoryGroupSet();
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.test.SpringTestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- _users = createUserSet();
- _groups = createGroupSet();
- _group = new Group("group0");
- _groups.add(_group);
- checkUserCount(0);
-
- }
-
- protected UserSet getUsers() {
- return _users;
- }
-
- protected GroupSet getGroups() {
- return _groups;
- }
-
- protected Group createGroup(String aName) {
- return new Group(aName);
- }
-
- protected User createUser(String aName, String aPassword, Group aGroup) throws UserMgtException {
- return UsermgtTestUtils.createUser(aName, aPassword, aGroup);
- }
-
- protected void addUserToGroup(User aUser, Group aGroup) throws UserMgtException {
- aUser.addGroup(aGroup);
- }
-
- protected void removeUserFromGroup(User aUser, Group aGroup ) throws UserMgtException {
- aUser.removeGroup(aGroup);
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aUser User to check for existence.
- */
- protected void checkUserExists(String aUser) throws SQLException {
- // Empty
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aUser User to check for non-existence.
- */
- protected void checkUserNotExists(String aUser) throws SQLException {
- // Empty
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aSize Expected number of users.
- */
- protected void checkUserCount(int aSize) throws SQLException {
- assertEquals(aSize, _users.size());
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aUser User to check for existence.
- */
- protected void checkGroupExists(String aUser) throws SQLException {
- // Empty
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aUser User to check for non-existence.
- */
- protected void checkGroupNotExists(String aUser) throws SQLException {
- // Empty
- }
-
- /**
- * Additional check to be implemented by a subclass.
- * @param aSize Expected number of users.
- */
- protected void checkGroupCount(int aSize) throws SQLException {
- // Empty
- }
-
-
- /**
- * Adds a user and verifies that the user is added using
- * find(), list(), and contains().
- *
- */
- public void testAdd() throws SQLException, UserMgtException {
- User user = createUser("user1", PASSWORD, _group);
- assertTrue( _users.add(user) );
- checkUserExists(user.getName());
- checkUserCount(1);
- User user2 = _users.find("user1");
- assertNotNull(user2);
- assertEquals(user.getName(), user2.getName());
- Set<User> set = _users.list();
- assertEquals(1, set.size());
- assertTrue(set.contains(user));
- }
-
- /**
- * Tries to find a non-existing user. Verifies that null is
- * returned.
- *
- */
- public void testFindUnknownUser() throws SQLException, UserMgtException {
- User user1 = createUser("user1", PASSWORD, _group);
- User user2 = createUser("user2", PASSWORD, _group);
- _users.add(user1);
- _users.add(user2);
- checkUserExists(user1.getName());
- checkUserExists(user2.getName());
-
- assertNull( _users.find("user3") );
- checkUserNotExists("user3");
- }
-
- /**
- * Adds duplicate user. Verifies that the existing user is left untouched.
- */
- public void testAddDuplicateUser() throws SQLException, UserMgtException {
- User user1 = createUser("user1", PASSWORD, _group);
- _users.add(user1);
-
- assertEquals(1, _users.list().size());
- assertTrue(_users.contains(user1));
- user1 = createUser("user1", PASSWORD, _group);
- assertFalse(_users.add(user1));
- assertEquals(1, _users.list().size());
-
- checkUserExists(user1.getName());
- checkUserCount(1);
- }
-
- /**
- * Removes a user. Verifies that the user is
- * removed and the return value is true.
- *
- */
- public void testRemoveUser() throws SQLException, UserMgtException {
- User user1 = createUser("user1", PASSWORD, _group);
- _users.add(user1);
- assertTrue(_users.contains(user1));
- checkUserCount(1);
-
- assertTrue(_users.remove(user1));
- assertFalse(_users.contains(user1));
- assertNull(_users.find(user1.getName()));
- assertEquals(0, _users.list().size());
- checkUserCount(0);
- }
-
- /**
- * Removes a non-existing user. Verifies that no users are
- * removed an that the return value is true.
- *
- */
- public void testRemoveNonExistingUser() throws SQLException, UserMgtException {
- User user1 = createUser("user1", PASSWORD, _group);
- _users.add(user1);
- checkUserCount(1);
- User nonExistingUser = createUser("user2", PASSWORD, _group);
- nonExistingUser.setPrimaryKey(new Long(1000));
- nonExistingUser.setPersistedVersion(10);
- assertFalse(_users.remove(nonExistingUser));
- assertTrue(_users.contains(user1));
- assertEquals(1, _users.list().size());
- checkUserCount(1);
- }
-
- /**
- * Adds a number of users to the set and verifies that list()
- * returns them all.
- *
- */
- public void testList() throws SQLException, UserMgtException {
- User user1 = createUser("user1", PASSWORD, _group);
- User user2 = createUser("user2", PASSWORD, _group);
- User user3 = createUser("user3", PASSWORD, _group);
- assertTrue(_users.add(user1));
- assertTrue(_users.add(user2));
- assertTrue(_users.add(user3));
-
- checkUserExists(user1.getName());
- checkUserExists(user2.getName());
- checkUserExists(user3.getName());
-
- Set<User> set = _users.list();
- assertTrue(set.contains(user1));
- assertTrue(set.contains(user2));
- assertTrue(set.contains(user3));
-
- checkUserCount(3);
- }
-
- /**
- * Adds several users to different groups and verifies that
- * the correct users are returned when looking for users in
- * different groups.
- * @throws SQLException
- */
- public void testListByGroup() throws SQLException, UserMgtException {
- Group group1 = new Group("group1");
- Group group2 = new Group("group2");
- Group group3 = new Group("group3");
- _groups.add(group1);
- _groups.add(group2);
- _groups.add(group3);
-
- // user1 user2 user3
- // group1 y
- // group2 y y
- // group3 y y y
-
- User user1 = createUser("user1", PASSWORD, group1);
- user1.addGroup(group2);
- user1.addGroup(group3);
- User user2 = createUser("user2", PASSWORD, group2);
- user2.addGroup(group3);
- User user3 = createUser("user3", PASSWORD, group3);
- _users.add(user1);
- _users.add(user2);
- _users.add(user3);
-
- checkUserExists(user1.getName());
- checkUserExists(user2.getName());
- checkUserExists(user3.getName());
-
- checkGroupExists(group1.getName());
- checkGroupExists(group2.getName());
- checkGroupExists(group3.getName());
-
- checkUserCount(3);
- checkGroupCount(3+1); // also count the group that was created in the setUp().
-
- Set<User> list = _users.list(group1);
- assertTrue(list.contains(user1));
- assertEquals(1, list.size());
-
- list = _users.list(group2);
- assertTrue(list.contains(user1));
- assertTrue(list.contains(user2));
- assertEquals(2, list.size());
-
- list = _users.list(group3);
- assertTrue(list.contains(user1));
- assertTrue(list.contains(user2));
- assertTrue(list.contains(user3));
- assertEquals(3, list.size());
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.core.Scope;
-import org.wamblee.system.spring.component.DatabaseTesterComponent;
-import org.wamblee.test.spring.TestTransactionCallback;
-import org.wamblee.usermgt.GroupSet;
-import org.wamblee.usermgt.InMemoryGroupSetTest;
-
-/**
- * Tests for {@link org.wamblee.usermgt.hibernate.HibernateGroupSet}
- *
- * @author Erik Brakkee
- */
-public class HibernateGroupSetTest extends InMemoryGroupSetTest {
-
- private static final String GROUP_TABLE = "GROUPS";
-
- private static final String GROUP_QUERY = "select * from " + GROUP_TABLE + " where name = ?";
-
- private DefaultContainer _container;
- private Scope _scope;
-
- private DatabaseTesterComponent _databaseTester;
- private GroupSet _groupSet;
-
- @Override
- protected void setUp() throws Exception {
-
- _container = new UserMgtRepositoryTestContainer("top");
-
- ObjectConfiguration config = new ObjectConfiguration(
- HibernateGroupSetTest.class);
- config.getSetterConfig().clear().add(
- "setGroupSet").add("setDatabaseTester");
- _container.addComponent("testcase", this, config);
-
- _scope = _container.start();
-
- _databaseTester.cleanDatabase();
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- _container.stop(_scope);
- super.tearDown();
- }
-
- public void setDatabaseTester(DatabaseTesterComponent aDatabaseTester) {
- _databaseTester = aDatabaseTester;
- }
-
- public void setGroupSet(GroupSet aGroupSet) {
- _groupSet = aGroupSet;
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupCount(int)
- */
- @Override
- protected void checkGroupCount(int aSize) throws SQLException {
- _databaseTester.flush();
- super.checkGroupCount(aSize);
- assertEquals(aSize, _databaseTester.getTableSize(GROUP_TABLE));
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupExists(java.lang.String)
- */
- @Override
- protected void checkGroupExists(final String aGroup) throws SQLException {
- _databaseTester.flush();
- Map<String,Integer> result =
- _databaseTester.executeTransaction(new TestTransactionCallback() {
- /* (non-Javadoc)
- * @see org.wamblee.test.TestTransactionCallback#execute()
- */
- @Override
- public Map execute() throws Exception {
- ResultSet result = _databaseTester.executeQuery(GROUP_QUERY, aGroup);
- Map<String,Integer> res = new HashMap<String,Integer>();
- res.put("result", _databaseTester.countResultSet(result));
- return res;
- }
- });
-
- int count = result.get("result");
- assertEquals(1, count);
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupNotExists(java.lang.String)
- */
- @Override
- protected void checkGroupNotExists(String aGroup) throws SQLException {
- _databaseTester.flush();
- ResultSet result = _databaseTester.executeQuery(GROUP_QUERY, aGroup);
- assertEquals(0, _databaseTester.countResultSet(result));
- }
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#createGroupSet()
- */
- @Override
- protected GroupSet createGroupSet() {
- return _groupSet;
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.sql.SQLException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.wamblee.cache.EhCache;
-import org.wamblee.system.adapters.ClassConfiguration;
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.components.DatabaseComponentFactory;
-import org.wamblee.system.core.Scope;
-import org.wamblee.system.spring.component.DatabaseTesterComponent;
-import org.wamblee.system.spring.component.DatasourceComponent;
-import org.wamblee.test.spring.TestTransactionCallbackWithoutResult;
-import org.wamblee.usermgt.UserAdministration;
-import org.wamblee.usermgt.UserAdministrationImplTest;
-
-/**
- * User administration tests with persistence based on Hibernate. This executes
- * the same test cases as {@link org.wamblee.usermgt.UserAdministrationImplTest}
- * with in addition, one test case that executes all Hibernate test cases
- * separately with each test case in its own transaction.
- *
- * @author Erik Brakkee
- */
-public class HibernateUserAdministrationTest extends UserAdministrationImplTest {
-
- private static final Log LOG = LogFactory.getLog(HibernateUserAdministrationTest.class);
-
- private DefaultContainer _container;
- private Scope _scope;
-
- private DatabaseTesterComponent _databaseTester;
- private EhCache<Serializable, Serializable> _userCache;
- private UserAdministration _userAdmin;
-
-
- /* (non-Javadoc)
- * @see org.wamblee.usermgt.UserAdministrationImplTest#setUp()
- */
- @Override
- protected void setUp() throws Exception {
-
- _container = new DefaultContainer("top");
- DatabaseComponentFactory.addDatabaseConfig(_container);
- _container.addComponent(new DatasourceComponent("datasource"));
- _container.addComponent(new UserAdministrationComponent("admin", true));
-
- ClassConfiguration dbtesterConfig = new ClassConfiguration(DatabaseTesterComponent.class);
- dbtesterConfig.getObjectConfig().getSetterConfig().initAllSetters();
- _container.addComponent("databaseTester", dbtesterConfig);
-
- ObjectConfiguration config = new ObjectConfiguration(
- HibernateUserAdministrationTest.class);
- config.getSetterConfig().clear().add(
- "setUserCache").add("setDatabaseTester").add("setUserAdmin");
- _container.addComponent("testcase", this, config);
-
- _scope = _container.start();
-
- _databaseTester.cleanDatabase();
-
- super.setUp();
- clearUserCache();
- }
-
- public void setUserCache(EhCache<Serializable, Serializable> aUserCache) {
- _userCache = aUserCache;
- }
-
- public void setDatabaseTester(DatabaseTesterComponent aDatabaseTester) {
- _databaseTester = aDatabaseTester;
- }
-
- public void setUserAdmin(UserAdministration aUserAdmin) {
- _userAdmin = aUserAdmin;
- }
-
- @Override
- protected void tearDown() throws Exception {
- _container.stop(_scope);
- super.tearDown();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.UserAdministrationImplTest#createAdmin()
- */
- @Override
- protected UserAdministration createAdmin() {
- return _userAdmin;
- }
-
- public void testAllTestsInASeparateTransaction() throws SQLException {
-
- Method[] methods = UserAdministrationImplTest.class.getMethods();
- for (final Method method : methods) {
- if (method.getName().startsWith("test")) {
- _databaseTester.cleanDatabase();
- clearUserCache();
- _databaseTester.executeTransaction(new TestTransactionCallbackWithoutResult() {
- public void execute() throws Exception {
- LOG.info("Running test " + method.getName());
- try {
- method.invoke(HibernateUserAdministrationTest.this);
- } catch (Throwable t) {
- LOG.error("Test " + method.getName() + " failed");
- throw new RuntimeException(t.getMessage(), t);
- }
- finally {
- LOG.info("Test " + method.getName() + " finished");
- }
-
- }
- });
- }
- }
- }
-
- /**
- *
- */
- private void clearUserCache() {
- _userCache.clear();
- }
-}
+++ /dev/null
-/*
- * Copyright 2005 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Set;
-
-import org.wamblee.cache.EhCache;
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.core.Scope;
-import org.wamblee.system.spring.component.DatabaseTesterComponent;
-import org.wamblee.usermgt.Group;
-import org.wamblee.usermgt.GroupSet;
-import org.wamblee.usermgt.InMemoryUserSetTest;
-import org.wamblee.usermgt.User;
-import org.wamblee.usermgt.UserMgtException;
-import org.wamblee.usermgt.UserSet;
-
-/**
- * Tests for {@link org.wamblee.usermgt.hibernate.HibernateGroupSet}
- *
- * @author Erik Brakkee
- */
-public class HibernateUserSetTest extends InMemoryUserSetTest {
-
- private static final String USER_TABLE = "USERS";
- private static final String GROUP_TABLE = "GROUPS";
-
- private static final String USER_QUERY = "select * from " + USER_TABLE
- + " where name = ?";
- private static final String GROUP_QUERY = "select * from " + GROUP_TABLE
- + " where name = ?";
-
- private DefaultContainer _container;
- private Scope _scope;
-
- private UserSet _userset;
- private GroupSet _groupset;
- private EhCache<Serializable, Serializable> _userCache;
- private DatabaseTesterComponent _databaseTester;
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryUserSetTest#setUp()
- */
- @Override
- protected void setUp() throws Exception {
-
- _container = new UserMgtRepositoryTestContainer("top");
-
- ObjectConfiguration config = new ObjectConfiguration(
- HibernateUserSetTest.class);
- config.getSetterConfig().clear().add("setUserset").add(
- "setGroupset").add("setDatabaseTester").add("setUserCache");
- _container.addComponent("testcase", this, config);
-
- _scope = _container.start();
-
- clearUserCache();
- _databaseTester.cleanDatabase();
-
- super.setUp();
- }
-
- public void setUserset(UserSet aUserset) {
- _userset = aUserset;
- }
-
- public void setGroupset(GroupSet aGroupset) {
- _groupset = aGroupset;
- }
-
- public void setUserCache(EhCache<Serializable, Serializable> aUserCache) {
- _userCache = aUserCache;
- }
-
- public void setDatabaseTester(DatabaseTesterComponent aDatabaseTester) {
- _databaseTester = aDatabaseTester;
- }
-
- @Override
- protected void tearDown() throws Exception {
- _container.stop(_scope);
- super.tearDown();
- }
-
- /**
- * Clears the user cache.
- */
- private void clearUserCache() {
- _userCache.clear();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupCount(int)
- */
- @Override
- protected void checkUserCount(int aSize) throws SQLException {
- _databaseTester.flush();
- super.checkUserCount(aSize);
- assertEquals(aSize, _databaseTester.getTableSize(USER_TABLE));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupExists(java.lang.String)
- */
- @Override
- protected void checkUserExists(String aUser) throws SQLException {
- _databaseTester.flush();
- ResultSet result = _databaseTester.executeQuery(USER_QUERY, aUser);
- assertEquals(1, _databaseTester.countResultSet(result));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupNotExists(java.lang.String)
- */
- @Override
- protected void checkUserNotExists(String aUser) throws SQLException {
- _databaseTester.flush();
- ResultSet result = _databaseTester.executeQuery(USER_QUERY, aUser);
- assertEquals(0, _databaseTester.countResultSet(result));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupCount(int)
- */
- @Override
- protected void checkGroupCount(int aSize) throws SQLException {
- _databaseTester.flush();
- assertEquals(aSize, _databaseTester.getTableSize(GROUP_TABLE));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupExists(java.lang.String)
- */
- @Override
- protected void checkGroupExists(String aGroup) throws SQLException {
- _databaseTester.flush();
-
- ResultSet result = _databaseTester.executeQuery(GROUP_QUERY, aGroup);
- assertEquals(1, _databaseTester.countResultSet(result));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#checkGroupNotExists(java.lang.String)
- */
- @Override
- protected void checkGroupNotExists(String aGroup) throws SQLException {
- _databaseTester.flush();
- ResultSet result = _databaseTester.executeQuery(GROUP_QUERY, aGroup);
- assertEquals(0, _databaseTester.countResultSet(result));
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryGroupSetTest#createGroupSet()
- */
- @Override
- protected UserSet createUserSet() {
- return _userset;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.usermgt.InMemoryUserSetTest#createGroupSet()
- */
- @Override
- protected GroupSet createGroupSet() {
- return _groupset;
- }
-
- /**
- * Reproduction of a bug. Create a user which is in group1 Add it to a
- * second group group2. Remove the user from group1. Verify the user is in
- * group2.
- */
- public void testVerifyAddRemove() throws SQLException, UserMgtException {
- _databaseTester.cleanDatabase(); // just to be sure.
- GroupSet groups = getGroups();
- assertEquals(0, groups.size());
- Group group1 = createGroup("group1");
- Group group2 = createGroup("group2");
- groups.add(group1);
- groups.add(group2);
- checkGroupExists("group1");
- checkGroupExists("group2");
-
- User user = createUser("user", PASSWORD, group1);
- getUsers().add(user);
- checkUserExists("user");
-
- addUserToGroup(user, group2);
- getUsers().userModified(user);
- clearUserCache();
- User user2 = getUsers().find("user");
- Set<Group> userGroups = user2.getGroups();
- assertTrue(user2.isInGroup("group1"));
- assertTrue(user2.isInGroup("group2"));
- assertEquals(2, userGroups.size());
-
- removeUserFromGroup(user, group1);
- getUsers().userModified(user);
- clearUserCache();
- user2 = getUsers().find("user");
- userGroups = user2.getGroups();
- assertFalse(user2.isInGroup("group1"));
- assertTrue(user2.isInGroup("group2"));
- assertEquals(1, userGroups.size());
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2008 the original author or authors.
- *
- * Licensed 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.wamblee.usermgt.hibernate;
-
-import java.io.IOException;
-
-import org.wamblee.system.adapters.ClassConfiguration;
-import org.wamblee.system.adapters.DefaultContainer;
-import org.wamblee.system.adapters.ObjectConfiguration;
-import org.wamblee.system.components.DatabaseComponentFactory;
-import org.wamblee.system.spring.component.DatabaseTesterComponent;
-import org.wamblee.system.spring.component.DatasourceComponent;
-import org.wamblee.system.spring.component.HibernateComponent;
-import org.wamblee.usermgt.UserGroupRepositoryComponent;
-
-/**
- *
- * Test container for repository tests of user management.
- *
- * @author Erik Brakkee
- */
-public class UserMgtRepositoryTestContainer extends DefaultContainer {
-
- public UserMgtRepositoryTestContainer(String aName) throws IOException {
- super(aName);
- DatabaseComponentFactory.addDatabaseConfig(this);
- addComponent(new DatasourceComponent("datasource"));
-
- ObjectConfiguration mappingFilesConfig = new ObjectConfiguration(UsermgtHibernateMappingFiles.class);
- mappingFilesConfig.getSetterConfig().initAllSetters();
- addComponent("mappingFiles", new UsermgtHibernateMappingFiles(), mappingFilesConfig);
- addComponent(new HibernateComponent("hibernate"));
- addComponent(new UserGroupRepositoryComponent("usersgroups"));
- ClassConfiguration dbtesterConfig = new ClassConfiguration(DatabaseTesterComponent.class);
- dbtesterConfig.getObjectConfig().getSetterConfig().initAllSetters();
- addComponent("databaseTester", dbtesterConfig);
-
- }
-
-}
<name>/support/general</name>
<url>http://wamblee.org</url>
<dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-api</artifactId>
+ </dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.cache;
import java.io.Serializable;
/**
- * The <code>Cache</code> interface represents... a cache.
- * In some circumstances it is more optimal to implement caching directly in
- * the code instead of relying on Hibernate caching methods. This interface abstracts
- * from the used cache implementation.
- * Cache implementations must be thread-safe.
+ * The <code>Cache</code> interface represents... a cache. In some circumstances
+ * it is more optimal to implement caching directly in the code instead of
+ * relying on Hibernate caching methods. This interface abstracts from the used
+ * cache implementation. Cache implementations must be thread-safe.
*/
public interface Cache<KeyType extends Serializable, ValueType extends Serializable> {
-
/**
- * Adds a key-value pair to the cache.
- * @param aKey Key.
- * @param aValue Value.
+ * Adds a key-value pair to the cache.
+ *
+ * @param aKey
+ * Key.
+ * @param aValue
+ * Value.
*/
- void put(KeyType aKey, ValueType aValue);
-
+ void put(KeyType aKey, ValueType aValue);
+
/**
- * Retrieves a value from the cache.
- * @param aKey Key to retrieve.
- * @return Key.
+ * Retrieves a value from the cache.
+ *
+ * @param aKey
+ * Key to retrieve.
+ *
+ * @return Key.
*/
ValueType get(KeyType aKey);
-
+
/**
- * Removes an entry from the cache.
- * @param aKey Key to remove the entry for.
+ * Removes an entry from the cache.
+ *
+ * @param aKey
+ * Key to remove the entry for.
*/
- void remove(KeyType aKey);
-
+ void remove(KeyType aKey);
+
/**
- * Removes all entries from the cache.
- *
+ * Removes all entries from the cache.
*/
- void clear();
+ void clear();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.cache;
-import java.io.Serializable;
-
import org.apache.log4j.Logger;
+import java.io.Serializable;
+
/**
* Represents a cached object. The object is either retrieved from the cache if
* the cache has it, or a call back is invoked to get the object (and put it in
* the cache).
- *
+ *
* @author Erik Brakkee
+ *
*/
public class CachedObject<KeyType extends Serializable, ValueType extends Serializable> {
-
private static final Logger LOGGER = Logger.getLogger(CachedObject.class);
- /**
- * Callback invoked to compute an object if it was not found in the cache.
- *
- * @param <T>
- * Type of the object
- */
- public static interface Computation<Key extends Serializable, Value extends Serializable> {
- /**
- * Gets the object. Called when the object is not in the cache.
- *
- * @param aObjectKey
- * Id of the object in the cache.
- * @return Object, must be non-null.
- */
- Value getObject(Key aObjectKey);
- }
-
/**
* Cache to use.
*/
- private Cache<KeyType, ValueType> _cache;
+ private Cache<KeyType, ValueType> cache;
/**
* Key of the object in the cache.
*/
- private KeyType _objectKey;
+ private KeyType objectKey;
/**
* Computation used to obtain the object if it is not found in the cache.
*/
- private Computation<KeyType, ValueType> _computation;
+ private Computation<KeyType, ValueType> computation;
/**
* Constructs the cached object.
* cache.
*/
public CachedObject(Cache<KeyType, ValueType> aCache, KeyType aObjectKey,
- Computation<KeyType, ValueType> aComputation) {
- _cache = aCache;
- _objectKey = aObjectKey;
- _computation = aComputation;
+ Computation<KeyType, ValueType> aComputation) {
+ cache = aCache;
+ objectKey = aObjectKey;
+ computation = aComputation;
}
/**
* @return Object.
*/
public ValueType get() {
- ValueType object = (ValueType) _cache.get(_objectKey); // the used
- // cache is
- // thread safe.
+ ValueType object = (ValueType) cache.get(objectKey); // the used
+ // cache is
+ // thread safe.
+
if (object == null) {
// synchronize the computation to make sure that the object is only
// computed
// be
// recomputed.
synchronized (this) {
- object = (ValueType) _cache.get(_objectKey);
+ object = (ValueType) cache.get(objectKey);
+
if (object == null) {
// No other thread did a recomputation so we must do this
// now.
- LOGGER.debug("Refreshing cache for '" + _objectKey + "'");
- object = _computation.getObject(_objectKey);
- _cache.put(_objectKey, object);
+ LOGGER.debug("Refreshing cache for '" + objectKey + "'");
+ object = computation.getObject(objectKey);
+ cache.put(objectKey, object);
}
}
}
+
return object;
}
/**
* Invalidates the cache for the object so that it is recomputed the next
* time it is requested.
- *
*/
public void invalidate() {
- _cache.remove(_objectKey);
+ cache.remove(objectKey);
}
/**
* @return Cache.
*/
public Cache getCache() {
- return _cache;
+ return cache;
+ }
+
+ /**
+ * Callback invoked to compute an object if it was not found in the cache.
+ *
+ * @param <T>
+ * Type of the object
+ */
+ public static interface Computation<Key extends Serializable, Value extends Serializable> {
+ /**
+ * Gets the object. Called when the object is not in the cache.
+ *
+ * @param aObjectKey
+ * Id of the object in the cache.
+ *
+ * @return Object, must be non-null.
+ */
+ Value getObject(Key aObjectKey);
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.cache;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.apache.log4j.Logger;
+
import org.wamblee.io.InputResource;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
/**
* Cache implemented on top of EhCache.
- *
+ *
* @author Erik Brakkee
+ *
*/
public class EhCache<KeyType extends Serializable, ValueType extends Serializable>
- implements org.wamblee.cache.Cache<KeyType, ValueType> {
-
+ implements org.wamblee.cache.Cache<KeyType, ValueType> {
private static final Logger LOGGER = Logger.getLogger(EhCache.class);
/**
* EH Cache manager.
*/
- private CacheManager _manager;
+ private CacheManager manager;
/**
* EH cache.
*/
- private Cache _cache;
+ private Cache cache;
/**
* Constructs a cache based on EHCache.
* @throws CacheException
*/
public EhCache(InputResource aResource, String aCacheName)
- throws IOException, CacheException {
+ throws IOException, CacheException {
InputStream is = aResource.getInputStream();
+
try {
- _manager = new CacheManager(is);
- _cache = _manager.getCache(aCacheName);
- if (_cache == null) {
- LOGGER.warn("Creating cache '" + aCacheName
- + "' because it is not configured");
- _manager.addCache(aCacheName);
- _cache = _manager.getCache(aCacheName);
+ manager = new CacheManager(is);
+ cache = manager.getCache(aCacheName);
+
+ if (cache == null) {
+ LOGGER.warn("Creating cache '" + aCacheName +
+ "' because it is not configured");
+ manager.addCache(aCacheName);
+ cache = manager.getCache(aCacheName);
}
- assert _cache != null;
+ assert cache != null;
} finally {
is.close();
}
-
}
/*
* @see org.wamblee.cache.Cache#put(KeyType, ValueType)
*/
public void put(KeyType aKey, ValueType aValue) {
- _cache.put(new Element(aKey, aValue));
+ cache.put(new Element(aKey, aValue));
}
/*
*/
public ValueType get(KeyType aKey) {
try {
- Element element = _cache.get(aKey);
+ Element element = cache.get(aKey);
+
if (element == null) {
return null;
}
+
return (ValueType) element.getValue();
} catch (CacheException e) {
throw new RuntimeException("Cache problem key = '" + aKey + "'", e);
* @see org.wamblee.cache.Cache#remove(KeyType)
*/
public void remove(KeyType aKey) {
- _cache.remove(aKey);
+ cache.remove(aKey);
}
/*
* @see org.wamblee.cache.Cache#clear()
*/
public void clear() {
- _cache.removeAll();
+ cache.removeAll();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.cache;
import java.io.Serializable;
+
import java.util.HashMap;
/**
* A very simple cache based on a HashMap, It never expires any entries, and has
* no bounds on its size.
- *
+ *
* @author Erik Brakkee
+ *
*/
public class ForeverCache<KeyType extends Serializable, ValueType extends Serializable>
- implements Cache<KeyType, ValueType> {
-
+ implements Cache<KeyType, ValueType> {
/**
* Cached entries.
*/
- private HashMap<KeyType, ValueType> _map;
+ private HashMap<KeyType, ValueType> map;
/**
* Constructs the cache.
*
*/
public ForeverCache() {
- _map = new HashMap<KeyType, ValueType>();
+ map = new HashMap<KeyType, ValueType>();
}
/*
* @see org.wamblee.cache.Cache#put(KeyType, ValueType)
*/
public synchronized void put(KeyType aKey, ValueType aValue) {
- _map.put(aKey, aValue);
+ map.put(aKey, aValue);
}
/*
* @see org.wamblee.cache.Cache#get(KeyType)
*/
public synchronized ValueType get(KeyType aKey) {
- return _map.get(aKey);
+ return map.get(aKey);
}
/*
* @see org.wamblee.cache.Cache#remove(KeyType)
*/
public synchronized void remove(KeyType aKey) {
- _map.remove(aKey);
+ map.remove(aKey);
}
/*
* @see org.wamblee.cache.Cache#clear()
*/
public synchronized void clear() {
- _map.clear();
+ map.clear();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.cache;
import java.io.Serializable;
/**
- * A cache that does not cache. This implementation is useful for disabling caching.
- * Because of this implementation, application code does not need to distinguish
- * between the situation where it a cache is used and where it isn't.
- *
+ * A cache that does not cache. This implementation is useful for disabling
+ * caching. Because of this implementation, application code does not need to
+ * distinguish between the situation where it a cache is used and where it
+ * isn't.
+ *
* @author Erik Brakkee
+ *
*/
-public class ZeroCache<KeyType extends Serializable, ValueType extends Serializable>
- implements Cache<KeyType, ValueType> {
-
- public ZeroCache() {
- // Empty.
+public class ZeroCache<KeyType extends Serializable, ValueType extends Serializable>
+ implements Cache<KeyType, ValueType> {
+ /**
+ * Creates a new ZeroCache object.
+ */
+ public ZeroCache() {
+ // Empty.
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.cache.Cache#put(KeyType, ValueType)
*/
public void put(KeyType aKey, ValueType aValue) {
- // Empty.
+ // Empty.
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.cache.Cache#get(KeyType)
*/
public ValueType get(KeyType aKey) {
return null;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.cache.Cache#remove(KeyType)
*/
public void remove(KeyType aKey) {
- // Empty
+ // Empty
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.cache.Cache#clear()
*/
public void clear() {
- // Empty
+ // Empty
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.collections;
-import java.util.Collection;
-
import org.wamblee.conditions.Condition;
-public class CollectionFilter {
+import java.util.Collection;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class CollectionFilter {
/**
- * Filters a collection by adding all elements in the from collection
- * that satisfy a given condition to the to collection.
- * @param <T> Type of contained element.
- * @param aFrom From container to which the condition is applied.
- * @param aTo To container to which matching elements are added.
- * @param aCondition Condition by which elements are matched.
+ * Filters a collection by adding all elements in the from collection that
+ * satisfy a given condition to the to collection.
+ *
+ * @param <T>
+ * Type of contained element.
+ * @param aFrom
+ * From container to which the condition is applied.
+ * @param aTo
+ * To container to which matching elements are added.
+ * @param aCondition
+ * Condition by which elements are matched.
*/
- public static <T> void filter(Collection<T> aFrom, Collection<T> aTo, Condition<T> aCondition) {
- for (T t: aFrom) {
- if ( aCondition.matches(t)) {
- aTo.add(t);
- }
- }
- }
-
+ public static <T> void filter(Collection<T> aFrom, Collection<T> aTo,
+ Condition<T> aCondition) {
+ for (T t : aFrom) {
+ if (aCondition.matches(t)) {
+ aTo.add(t);
+ }
+ }
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.concurrency;
import java.util.concurrent.locks.ReentrantLock;
/**
- * In memory JVM lock.
- *
+ * In memory JVM lock.
+ *
* @author Erik Brakkee
- */
+ */
public class JvmLock implements Lock {
-
/**
- * Reentrant lock to use.
+ * Reentrant lock to use.
*/
- private ReentrantLock _lock;
-
+ private ReentrantLock lock;
+
/**
- * In-memory lock.
+ * In-memory lock.
*/
- public JvmLock() {
- _lock = new ReentrantLock(true);
+ public JvmLock() {
+ lock = new ReentrantLock(true);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.concurrency.Lock#acquire()
*/
public void acquire() {
- _lock.lock();
+ lock.lock();
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.concurrency.Lock#release()
*/
public void release() {
- _lock.unlock();
+ lock.unlock();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.concurrency;
/**
- * Represents a re-entrant lock.
- * Implementations can provide inmemory JVM locking or full cluster safe locking
- * mechanisms.
- *
+ * Represents a re-entrant lock. Implementations can provide inmemory JVM
+ * locking or full cluster safe locking mechanisms.
+ *
* @author Erik Brakkee
*/
public interface Lock {
-
/**
- * Acquires the lock.
+ * Acquires the lock.
*/
- void acquire();
-
+ void acquire();
+
/**
- * Releases the lock.
+ * Releases the lock.
*/
- void release();
+ void release();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.HashSet;
-
/**
* Read-write lock for allowing multiple concurrent readers or at most one
* writer. This implementation does not aim for high performance but for
*/
public class ReadWriteLock {
/**
- * Sets containing the references to the threads that are currently
- * reading. This administration is useful to check that the lock has
- * already been acquired before it is release. This check adds robustness
- * to the application.
+ * Sets containing the references to the threads that are currently reading.
+ * This administration is useful to check that the lock has already been
+ * acquired before it is release. This check adds robustness to the
+ * application.
*/
- private HashSet<Thread> _readers;
+ private HashSet<Thread> readers;
/**
* The thread that has acquired the lock for writing or null if no such
* thread exists currently.
*/
- private Thread _writer;
+ private Thread writer;
/**
* Constructs read-write lock.
*/
public ReadWriteLock() {
- _readers = new HashSet<Thread>();
- _writer = null;
+ readers = new HashSet<Thread>();
+ writer = null;
}
/**
- * Acquires the lock for reading. This call will block until the lock can
- * be acquired.
- *
- * @throws IllegalStateException Thrown if the read or write lock is
- * already acquired.
+ * Acquires the lock for reading. This call will block until the lock can be
+ * acquired.
+ *
+ * @throws IllegalStateException
+ * Thrown if the read or write lock is already acquired.
*/
public synchronized void acquireRead() {
- if (_readers.contains(Thread.currentThread())) {
+ if (readers.contains(Thread.currentThread())) {
throw new IllegalStateException(
- "Read lock already acquired by current thread: "
- + Thread.currentThread());
+ "Read lock already acquired by current thread: " +
+ Thread.currentThread());
}
- if (_writer == Thread.currentThread()) {
+ if (writer == Thread.currentThread()) {
throw new IllegalStateException(
- "Trying to acquire the read lock while already holding a write lock: "
- + Thread.currentThread());
+ "Trying to acquire the read lock while already holding a write lock: " +
+ Thread.currentThread());
}
- while (_writer != null) {
+ while (writer != null) {
try {
wait();
} catch (InterruptedException e) {
}
}
- _readers.add(Thread.currentThread());
+ readers.add(Thread.currentThread());
}
/**
- * Releases the lock for reading. Note: This implementation assumes that
- * the lock has already been acquired for reading previously.
- *
- * @throws IllegalStateException Thrown when the lock was not acquired by
- * this thread.
+ * Releases the lock for reading. Note: This implementation assumes that the
+ * lock has already been acquired for reading previously.
+ *
+ * @throws IllegalStateException
+ * Thrown when the lock was not acquired by this thread.
*/
public synchronized void releaseRead() {
- if (!_readers.remove(Thread.currentThread())) {
+ if (!readers.remove(Thread.currentThread())) {
throw new IllegalStateException(
"Cannot release read lock because current thread has not acquired it.");
}
- if (_readers.size() == 0) {
+ if (readers.size() == 0) {
notifyAll();
}
}
/**
* Acquires the lock for writing. This call will block until the lock has
* been acquired.
- *
- * @throws IllegalStateException Thrown if the read or write lock is
- * already acquired.
+ *
+ * @throws IllegalStateException
+ * Thrown if the read or write lock is already acquired.
*/
public synchronized void acquireWrite() {
- if (_writer == Thread.currentThread()) {
+ if (writer == Thread.currentThread()) {
throw new IllegalStateException(
- "Trying to acquire a write lock while already holding the write lock: "
- + Thread.currentThread());
+ "Trying to acquire a write lock while already holding the write lock: " +
+ Thread.currentThread());
}
- if (_readers.contains(Thread.currentThread())) {
+ if (readers.contains(Thread.currentThread())) {
throw new IllegalStateException(
- "Trying to acquire a write lock while already holding the read lock: "
- + Thread.currentThread());
+ "Trying to acquire a write lock while already holding the read lock: " +
+ Thread.currentThread());
}
// wait until there are no more writers and no more
- // readers
- while ((_writer != null) || (_readers.size() > 0)) {
+ // readers
+ while ((writer != null) || (readers.size() > 0)) {
try {
wait();
} catch (InterruptedException e) {
}
}
- _writer = Thread.currentThread();
+ writer = Thread.currentThread();
// notification not necessary since all writers and
// readers are now blocked by this thread.
/**
* Releases the lock for writing.
- *
- * @throws IllegalStateException Thrown when the lock was not acquired.
+ *
+ * @throws IllegalStateException
+ * Thrown when the lock was not acquired.
*/
public synchronized void releaseWrite() {
- if (_writer != Thread.currentThread()) {
+ if (writer != Thread.currentThread()) {
throw new IllegalStateException(
"Cannot release write lock because it was not acquired. ");
}
- _writer = null;
+ writer = null;
notifyAll();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.conditions;
import java.util.ArrayList;
/**
* Represents a logical and of different boolean conditions.
- *
+ *
* @author Erik Brakkee
+ *
*/
public class AndCondition<T> implements Condition<T> {
-
- private List<Condition<T>> _conditions;
+ private List<Condition<T>> conditions;
/**
* Constructs the condition.
* Second condition.
*/
public AndCondition(Condition<T> aCondition1, Condition<T> aCondition2) {
- _conditions = new ArrayList<Condition<T>>();
- _conditions.add(aCondition1);
- _conditions.add(aCondition2);
+ conditions = new ArrayList<Condition<T>>();
+ conditions.add(aCondition1);
+ conditions.add(aCondition2);
}
/**
* List of conditions to use in the logical and.
*/
public AndCondition(List<Condition<T>> aConditions) {
- _conditions = aConditions;
+ conditions = aConditions;
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.crawler.kiss.ProgramMatcher#matches(org.wamblee.crawler.kiss.Program)
+ * @see
+ * org.wamblee.crawler.kiss.ProgramMatcher#matches(org.wamblee.crawler.kiss
+ * .Program)
*/
public boolean matches(T aObject) {
- for (Condition<T> condition : _conditions) {
+ for (Condition<T> condition : conditions) {
if (!condition.matches(aObject)) {
return false;
}
}
+
return true;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
-
/**
* Determines if an object matches a certain condition.
- *
+ *
* @author Erik Brakkee
*/
public interface Condition<T> {
-
/**
- * Determines if an object matches a condition.
- * @param aObject object to match.
- * @return True iff the object matches.
+ * Determines if an object matches a condition.
+ *
+ * @param aObject
+ * object to match.
+ *
+ * @return True iff the object matches.
*/
- boolean matches(T aObject);
+ boolean matches(T aObject);
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
/**
- * Condition which always returns a fixed value.
- *
+ * Condition which always returns a fixed value.
+ *
* @author Erik Brakkee
+ *
*/
public class FixedCondition<T> implements Condition<T> {
-
- private boolean _value;
-
+ private boolean value;
+
/**
- * Constructs the condition.
- * @param aValue Fixed value of the condition.
+ * Constructs the condition.
+ *
+ * @param aValue
+ * Fixed value of the condition.
*/
- public FixedCondition(boolean aValue) {
- _value = aValue;
+ public FixedCondition(boolean aValue) {
+ value = aValue;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.conditions.Condition#matches(T)
*/
public boolean matches(T aObject) {
- return _value;
+ return value;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.conditions;
import java.util.ArrayList;
/**
* Represents a logical or of different boolean conditions.
- *
+ *
* @author Erik Brakkee
+ *
*/
public class OrCondition<T> implements Condition<T> {
-
- private List<Condition<T>> _conditions;
+ private List<Condition<T>> conditions;
/**
* Constructs the condition.
* Second condition.
*/
public OrCondition(Condition<T> aCondition1, Condition<T> aCondition2) {
- _conditions = new ArrayList<Condition<T>>();
- _conditions.add(aCondition1);
- _conditions.add(aCondition2);
+ conditions = new ArrayList<Condition<T>>();
+ conditions.add(aCondition1);
+ conditions.add(aCondition2);
}
/**
* List of conditions to use in the logical or.
*/
public OrCondition(List<Condition<T>> aConditions) {
- _conditions = aConditions;
+ conditions = aConditions;
}
/*
* (non-Javadoc)
*
- * @see org.wamblee.crawler.kiss.ProgramMatcher#matches(org.wamblee.crawler.kiss.Program)
+ * @see
+ * org.wamblee.crawler.kiss.ProgramMatcher#matches(org.wamblee.crawler.kiss
+ * .Program)
*/
public boolean matches(T aObject) {
- for (Condition<T> condition : _conditions) {
+ for (Condition<T> condition : conditions) {
if (condition.matches(aObject)) {
return true;
}
}
+
return false;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
+import org.apache.commons.beanutils.PropertyUtils;
+
import java.lang.reflect.InvocationTargetException;
+
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.commons.beanutils.PropertyUtils;
-
/**
- * Condition to check whether a given property value matches a certain
- * regular expression.
- *
+ * Condition to check whether a given property value matches a certain regular
+ * expression.
+ *
* @author Erik Brakkee
+ *
*/
public class PropertyRegexCondition<T> implements Condition<T> {
-
/**
- * Property name.
+ * Property name.
*/
- private String _property;
-
+ private String property;
+
/**
- * Regular expression.
+ * Regular expression.
*/
- private Pattern _regex;
-
+ private Pattern regex;
+
/**
- * Whether or not to convert the value to lowercase before matching.
+ * Whether or not to convert the value to lowercase before matching.
*/
- private boolean _tolower;
-
+ private boolean tolower;
+
/**
- * Constructs the condition.
- * @param aProperty Name of the property to examine.
- * @param aRegex Regular expression to use.
- * @param aTolower Whether or not to convert the value to lowercase before matching.
+ * Constructs the condition.
+ *
+ * @param aProperty
+ * Name of the property to examine.
+ * @param aRegex
+ * Regular expression to use.
+ * @param aTolower
+ * Whether or not to convert the value to lowercase before
+ * matching.
*/
- public PropertyRegexCondition(String aProperty, String aRegex, boolean aTolower) {
- _property = aProperty;
- _regex = Pattern.compile(aRegex);
- _tolower = aTolower;
+ public PropertyRegexCondition(String aProperty, String aRegex,
+ boolean aTolower) {
+ property = aProperty;
+ regex = Pattern.compile(aRegex);
+ tolower = aTolower;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.conditions.Condition#matches(T)
*/
public boolean matches(T aObject) {
try {
- String value = PropertyUtils.getProperty(aObject, _property) + "";
- if ( _tolower ) {
- value = value.toLowerCase();
+ String value = PropertyUtils.getProperty(aObject, property) + "";
+
+ if (tolower) {
+ value = value.toLowerCase();
}
- Matcher matcher = _regex.matcher(value);
- return matcher.matches();
+
+ Matcher matcher = regex.matcher(value);
+
+ return matcher.matches();
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage(), e);
} catch (InvocationTargetException e) {
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.general;
/**
- * Bean factory used to obtain objects in a transparent way.
- *
+ * Bean factory used to obtain objects in a transparent way.
+ *
* @author Erik Brakkee
*/
public interface BeanFactory {
-
- /**
- * Finds a bean based on id.
- * @param aId Id of the bean.
- * @return Object (always non-null).
- * @throws BeanFactoryException In case the object could not be found.
- */
- Object find(String aId);
-
/**
- * Finds a bean of the given class and which can be cast to the
- * specified class. This is typically used by specifying the interface
- * class for retrieving an implementation of that class. This
- * means that the bean implementing the class is configured in the bean factory
- * with id equal to the class name of the interface.
- * @param aClass Class of the object to find.
+ * Finds a bean based on id.
+ *
+ * @param aId
+ * Id of the bean.
* @return Object (always non-null).
- * @throws BeanFactoryException In case the object could not be found.
+ * @throws BeanFactoryException
+ * In case the object could not be found.
*/
- <T> T find(Class<T> aClass);
-
- /**
- * Finds a bean with the given id which can be cast to the specified
- * class.
- * @param <T> Type of the object to get.
- * @param aId Id of the object to lookup.
- * @param aClass Class that the object must extends.
- * @return Object, always non-null.
- * @throws BeanFactoryException In case the object could not be found.
- */
- <T> T find(String aId, Class<T> aClass);
+ Object find(String aId);
+
+ <T> T find(Class<T> aClass);
+
+ <T> T find(String aId, Class<T> aClass);
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.general;
/**
- * Exception thrown by the BeanFactory if an object could not be found.
- *
+ * Exception thrown by the BeanFactory if an object could not be found.
+ *
* @author Erik Brakkee
*/
public class BeanFactoryException extends RuntimeException {
static final long serialVersionUID = -1215992188624874902L;
/**
- * Constructs the exception.
- * @param aMsg Message.
+ * Constructs the exception.
+ *
+ * @param aMsg
+ * Message.
*/
- public BeanFactoryException(String aMsg) {
- super(aMsg);
+ public BeanFactoryException(String aMsg) {
+ super(aMsg);
}
-
+
/**
- * Constructs the exception.
- * @param aMsg Message.
- * @param aThrowable Cause of the exception.
+ * Constructs the exception.
+ *
+ * @param aMsg
+ * Message.
+ * @param aThrowable
+ * Cause of the exception.
*/
public BeanFactoryException(String aMsg, Throwable aThrowable) {
super(aMsg, aThrowable);
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.general;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.wamblee.io.ClassPathResource;
import org.wamblee.io.InputResource;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.util.Properties;
+
/**
* The standard means to obtain the bean factory. This works by reading a
* property {@value #BEAN_FACTORY_CLASS} from a property file named
* a no-arg constructor.
*/
public final class BeanKernel {
-
private static final Log LOG = LogFactory.getLog(BeanKernel.class);
/**
BEAN_FACTORY = lookupBeanFactory(BEAN_KERNEL_PROP_FILE);
}
}
+
return BEAN_FACTORY;
}
/**
* Lookup the bean factory based on the properties file.
*
+ *
* @return Bean factory.
+ *
*/
static BeanFactory lookupBeanFactory(String aPropertyFilename) {
InputResource resource = new ClassPathResource(aPropertyFilename);
InputStream is;
+
try {
is = resource.getInputStream();
} catch (IOException e) {
throw new BeanFactoryException("Cannot open resource " + resource,
- e);
+ e);
}
+
try {
Properties props = new Properties();
props.load(is);
+
String className = props.getProperty(BEAN_FACTORY_CLASS);
Class beanFactory = Class.forName(className);
+
return (BeanFactory) beanFactory.newInstance();
} catch (Exception e) {
- throw new BeanFactoryException("Cannot read from resource "
- + resource, e);
+ throw new BeanFactoryException("Cannot read from resource " +
+ resource, e);
} finally {
try {
is.close();
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.general;
-import java.io.IOException;
import java.io.File;
-import java.net.URLClassLoader;
-import java.net.URL;
+import java.io.IOException;
+
import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
/**
* Utility for working with the class loader. Based on the ClassPathHacker
- * example found on the internet.
+ * example found on the internet.
*/
public class ClassLoaderUtils {
-
// No logging in this class to keep the required class libraries
// limited to the standard java classes. This allows use of the
- // utilities in an environment with a very limited classpath.
-
+ // utilities in an environment with a very limited classpath.
private static final String JAR_SUFFIX = ".jar";
/**
- * Adds all jars in the given directory to the class path.
- * @param aDirectory Directory.
+ * Adds all jars in the given directory to the class path.
+ *
+ * @param aDirectory
+ * Directory.
* @throws IOException
*/
public static void addJarsInDirectory(File aDirectory) throws IOException {
for (File aFile : aDirectory.listFiles()) {
System.out
- .println("Considering '" + aFile.getCanonicalPath() + "'");
+ .println("Considering '" + aFile.getCanonicalPath() + "'");
+
if (aFile.getName().toLowerCase().endsWith(JAR_SUFFIX)) {
- System.out.println("Adding '" + aFile.getCanonicalPath()
- + "' to classpath.");
+ System.out.println("Adding '" + aFile.getCanonicalPath() +
+ "' to classpath.");
addFile(aFile);
}
}
/**
* Adds a file to the classpath.
- * @param aFilename Filename to add.
+ *
+ * @param aFilename
+ * Filename to add.
* @throws IOException
*/
public static void addFile(String aFilename) throws IOException {
}
/**
- * Adds a file to the classpath.
- * @param aFile File to add.
+ * Adds a file to the classpath.
+ *
+ * @param aFile
+ * File to add.
* @throws IOException
*/
public static void addFile(File aFile) throws IOException {
/**
* Adds a url to the classpath.
- * @param aUrl Url to add.
+ *
+ * @param aUrl
+ * Url to add.
* @throws IOException
*/
public static void addURL(URL aUrl) throws IOException {
-
URLClassLoader sysloader = (URLClassLoader) ClassLoader
- .getSystemClassLoader();
+ .getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
- Method method = sysclass.getDeclaredMethod("addURL", new Class[]{ URL.class } );
+ Method method = sysclass.getDeclaredMethod("addURL",
+ new Class[] { URL.class });
method.setAccessible(true);
method.invoke(sysloader, new Object[] { aUrl });
} catch (Throwable t) {
t.printStackTrace();
throw new IOException(
- "Error, could not add URL to system classloader");
+ "Error, could not add URL to system classloader");
}
-
}
-
}
-
-
-
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.general;
/**
* Type of the first object.
* @param <U>
* Type of the second object.
- *
+ *
* @author Erik Brakkee
*/
public class Pair<T, U> {
-
- private T _t;
-
- private U _u;
+ private T t;
+ private U u;
/**
* Constructs the pair.
* Second object.
*/
public Pair(T aT, U aU) {
- _t = aT;
- _u = aU;
+ t = aT;
+ u = aU;
}
/**
* Pair to copy.
*/
public Pair(Pair<T, U> aPair) {
- _t = aPair._t;
- _u = aPair._u;
+ t = aPair.t;
+ u = aPair.u;
}
/**
* @return First object.
*/
public T getFirst() {
- return _t;
+ return t;
}
/**
* @return Second object.
*/
public U getSecond() {
- return _u;
+ return u;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
import java.io.IOException;
/**
* Resource name.
*/
- private String _resource;
+ private String resource;
/**
* Construct the class path resource.
* Resource
*/
public ClassPathResource(String aResource) {
- _resource = aResource;
+ resource = aResource;
}
/*
*/
public InputStream getInputStream() throws IOException {
InputStream stream = Thread.currentThread().getContextClassLoader()
- .getResourceAsStream(_resource);
+ .getResourceAsStream(resource);
+
if (stream == null) {
- throw new IOException("Class path resource '" + _resource
- + "' not found.");
+ throw new IOException("Class path resource '" + resource +
+ "' not found.");
}
+
return stream;
}
* @see java.lang.Object#toString()
*/
public String toString() {
- return "ClassPathResource(" + _resource + ")";
+ return "ClassPathResource(" + resource + ")";
}
}
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import java.io.File;
import java.io.FileFilter;
+
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
/**
* Monitors a directory for changes.
*
* @author Erik Brakkee
*/
public class DirectoryMonitor {
+ private static final Log LOG = LogFactory.getLog(DirectoryMonitor.class);
+
+ private File directory;
+
+ private FileFilter filter;
+
+ private Listener listener;
+
+ private Map<File, Date> contents;
+
+ /**
+ * Creates a new DirectoryMonitor object.
+ *
+ */
+ public DirectoryMonitor(File aDirectory, FileFilter aFilefilter,
+ Listener aListener) {
+ directory = aDirectory;
+
+ if (!directory.isDirectory()) {
+ throw new IllegalArgumentException("Directory '" + directory +
+ "' does not exist");
+ }
+
+ filter = aFilefilter;
+ listener = aListener;
+ contents = new HashMap<File, Date>();
+ }
+
+ /**
+ * Polls the directory for changes and notifies the listener of any changes.
+ * In case of any exceptions thrown by the listener while handling the
+ * changes, the next call to this method will invoked the listeners again
+ * for the same changes.
+ */
+ public void poll() {
+ LOG.debug("Polling " + directory);
+
+ Map<File, Date> newContents = new HashMap<File, Date>();
+ File[] files = directory.listFiles(filter);
+
+ // Check deleted files.
+ Set<File> deletedFiles = new HashSet<File>(contents.keySet());
+
+ for (File file : files) {
+ if (file.isFile()) {
+ if (contents.containsKey(file)) {
+ deletedFiles.remove(file);
+ }
+ }
+ }
+
+ for (File file : deletedFiles) {
+ listener.fileDeleted(file);
+ }
+
+ for (File file : files) {
+ if (file.isFile()) {
+ if (contents.containsKey(file)) {
+ Date oldDate = contents.get(file);
+
+ if (file.lastModified() != oldDate.getTime()) {
+ listener.fileChanged(file);
+ } else {
+ // No change.
+ }
+
+ newContents.put(file, new Date(file.lastModified()));
+ } else {
+ listener.fileCreated(file);
+ newContents.put(file, new Date(file.lastModified()));
+ }
+ }
+ }
+
+ contents = newContents;
+ }
+
+ public static interface Listener {
+ void fileChanged(File aFile);
- private static final Log LOG = LogFactory.getLog(DirectoryMonitor.class);
-
- public static interface Listener {
-
- void fileChanged(File aFile);
-
- void fileCreated(File aFile);
-
- void fileDeleted(File aFile);
- };
-
- private File _directory;
- private FileFilter _filter;
- private Listener _listener;
- private Map<File, Date> _contents;
-
- public DirectoryMonitor(File aDirectory, FileFilter aFilefilter,
- Listener aListener) {
- _directory = aDirectory;
- if (!_directory.isDirectory()) {
- throw new IllegalArgumentException("Directory '" + _directory
- + "' does not exist");
- }
- _filter = aFilefilter;
- _listener = aListener;
- _contents = new HashMap<File, Date>();
- }
-
- /**
- * Polls the directory for changes and notifies the listener of any changes.
- * In case of any exceptions thrown by the listener while handling the changes,
- * the next call to this method will invoked the listeners again for the same changes.
- */
- public void poll() {
- LOG.debug("Polling " + _directory);
- Map<File, Date> newContents = new HashMap<File, Date>();
- File[] files = _directory.listFiles(_filter);
-
- // Check deleted files.
- Set<File> deletedFiles = new HashSet<File>(_contents.keySet());
- for (File file : files) {
- if (file.isFile()) {
- if (_contents.containsKey(file)) {
- deletedFiles.remove(file);
- }
- }
- }
- for (File file : deletedFiles) {
- _listener.fileDeleted(file);
- }
-
- for (File file : files) {
- if (file.isFile()) {
- if (_contents.containsKey(file)) {
- Date oldDate = _contents.get(file);
- if (file.lastModified() != oldDate.getTime()) {
- _listener.fileChanged(file);
- } else {
- // No change.
- }
- newContents.put(file, new Date(file.lastModified()));
- } else {
- _listener.fileCreated(file);
- newContents.put(file, new Date(file.lastModified()));
- }
- }
- }
-
- _contents = newContents;
- }
+ void fileCreated(File aFile);
+ void fileDeleted(File aFile);
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
import java.io.BufferedInputStream;
/**
* Resource implemention for reading from a file.
- *
+ *
* @author Erik Brakkee
*/
public class FileResource implements InputResource {
/**
* File to read.
*/
- private File _file;
+ private File file;
/**
* Constructs the resource.
* File to read.
*/
public FileResource(File aFile) {
- _file = aFile;
+ file = aFile;
}
/*
* @see org.wamblee.io.InputResource#getInputStream()
*/
public InputStream getInputStream() throws IOException {
- return new BufferedInputStream(new FileInputStream(_file));
+ return new BufferedInputStream(new FileInputStream(file));
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
import java.io.IOException;
/**
* Represents a resource from which information can be read.
- *
+ *
* @author Erik Brakkee
*/
public interface InputResource {
* closed once reading has finished.
*
* @return Input stream to the resource, never null.
+ *
* @throws IOException
* in case the resource cannot be found.
*/
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
import java.io.StringWriter;
import java.io.Writer;
+import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class SimpleProcess {
+ private static final Log LOG = LogFactory.getLog(SimpleProcess.class);
- private static final Log LOG = LogFactory.getLog(SimpleProcess.class);
+ private File directory;
- private File _directory;
+ private String[] cmd;
- private String[] _cmd;
-
- private String _stdout;
- private String _stderr;
+ private String stdout;
- public SimpleProcess(File aDirectory, String[] aCmd) {
- _directory = aDirectory;
- _cmd = aCmd;
- }
+ private String stderr;
/**
+ * Creates a new SimpleProcess object.
+ *
+ */
+ public SimpleProcess(File aDirectory, String[] aCmd) {
+ directory = aDirectory;
+ cmd = Arrays.copyOf(aCmd, aCmd.length);
+ }
+
+ /**
+ *
* @return the stdout
*/
public String getStdout() {
- return _stdout;
+ return stdout;
}
-
+
/**
+ *
* @return the stderr
*/
public String getStderr() {
- return _stderr;
+ return stderr;
+ }
+
+ /**
+ * Runs the process and blocks until it is done.
+ *
+ * @return Exit status of the process.
+ *
+ * @throws IOException
+ * In case of problems.
+ */
+ public int run() throws IOException {
+ return runImpl();
+ }
+
+ private int runImpl() throws IOException {
+ try {
+ StringBuffer fullcmd = new StringBuffer();
+
+ for (String part : cmd) {
+ fullcmd.append(" " + part);
+ }
+
+ LOG.debug("Executing '" + fullcmd + "' in directory '" + directory +
+ "'");
+
+ java.lang.Process proc = Runtime.getRuntime().exec(cmd, null,
+ directory);
+
+ // Read standard output and error in separate threads to avoid
+ // deadlock.
+ StringWriter myStdout = new StringWriter();
+ StringWriter myStderr = new StringWriter();
+ Thread stdoutReader = readAndLogStream("STDOUT> ", proc
+ .getInputStream(), myStdout);
+ Thread stderrReader = readAndLogStream("STDERR> ", proc
+ .getErrorStream(), myStderr);
+
+ try {
+ proc.waitFor();
+ } catch (InterruptedException e) {
+ IOException exception = new IOException(
+ "Process was terminated: " + this);
+ exception.initCause(e);
+ throw exception;
+ }
+
+ waitForReader(stdoutReader);
+ waitForReader(stderrReader);
+
+ stdout = myStdout.toString();
+ stderr = myStderr.toString();
+
+ if (proc.exitValue() != 0) {
+ LOG.warn("Exit value was non-zero: " + this);
+ } else {
+ LOG.debug("Process finished");
+ }
+
+ return proc.exitValue();
+ } catch (IOException e) {
+ IOException exception = new IOException(
+ "Error executing process: " + this);
+ exception.initCause(e);
+ throw exception;
+ }
}
-
- /**
- * Runs the process and blocks until it is done.
- *
- * @return Exit status of the process.
- * @throws IOException
- * In case of problems.
- */
- public int run() throws IOException {
- return runImpl();
- }
-
- private int runImpl() throws IOException {
- try {
- String fullcmd = "";
- for (String part: _cmd) {
- fullcmd += " " + part;
- }
- LOG.debug("Executing '" + fullcmd + "' in directory '" + _directory
- + "'");
- java.lang.Process proc = Runtime.getRuntime().exec(_cmd, null, _directory);
-
- // Read standard output and error in separate threads to avoid
- // deadlock.
-
- StringWriter stdout = new StringWriter();
- StringWriter stderr = new StringWriter();
- Thread stdoutReader = readAndLogStream("STDOUT> ", proc
- .getInputStream(), stdout);
- Thread stderrReader = readAndLogStream("STDERR> ", proc
- .getErrorStream(), stderr);
-
- try {
- proc.waitFor();
- } catch (InterruptedException e) {
- IOException exception = new IOException(
- "Process was terminated: " + this);
- exception.initCause(e);
- throw exception;
- }
- waitForReader(stdoutReader);
- waitForReader(stderrReader);
-
- _stdout = stdout.toString();
- _stderr = stderr.toString();
-
- if (proc.exitValue() != 0) {
- LOG.warn("Exit value was non-zero: " + this);
- } else {
- LOG.debug("Process finished");
- }
- return proc.exitValue();
- } catch (IOException e) {
- IOException exception = new IOException("Error executing process: "
- + this);
- exception.initCause(e);
- throw exception;
- }
- }
-
- private void waitForReader(Thread aReaderThread) {
- try {
- aReaderThread.join();
- } catch (InterruptedException e) {
- LOG
- .warn(this
- + ": error waiting for output stream reader of process to finish");
- }
- }
-
- private Thread readAndLogStream(final String aPrefix,
- final InputStream aStream, final Writer aOutput) {
- Thread inputReader = new Thread() {
- @Override
- public void run() {
- BufferedReader br = null;
- try {
- br = new BufferedReader(new InputStreamReader(aStream));
- String str;
- while ((str = br.readLine()) != null) {
- LOG.debug(aPrefix + str);
+
+ private void waitForReader(Thread aReaderThread) {
+ try {
+ aReaderThread.join();
+ } catch (InterruptedException e) {
+ LOG
+ .warn(this +
+ ": error waiting for output stream reader of process to finish");
+ }
+ }
+
+ private Thread readAndLogStream(final String aPrefix,
+ final InputStream aStream, final Writer aOutput) {
+ Thread inputReader = new Thread() {
+ @Override
+ public void run() {
+ BufferedReader br = null;
+
+ try {
+ br = new BufferedReader(new InputStreamReader(aStream));
+
+ String str;
+
+ while ((str = br.readLine()) != null) {
+ LOG.debug(aPrefix + str);
aOutput.write(str);
- }
- } catch (IOException e) {
- LOG.warn(SimpleProcess.this + ": error reading input stream", e);
- } finally {
- if (br != null) {
- try {
- br.close();
- } catch (IOException e) {
- LOG.warn("Error closing stream " + aPrefix);
- }
- }
- }
- }
- };
- inputReader.start();
- return inputReader;
- }
-
- @Override
- public String toString() {
- String fullcmd = "";
- for (String part: _cmd) {
- fullcmd += part + " ";
+ }
+ } catch (IOException e) {
+ LOG.warn(SimpleProcess.this +
+ ": error reading input stream", e);
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ LOG.warn("Error closing stream " + aPrefix);
+ }
+ }
+ }
+ }
+ };
+
+ inputReader.start();
+
+ return inputReader;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer fullcmd = new StringBuffer();
+
+ for (String part : cmd) {
+ fullcmd.append(part + " ");
}
- return "process(dir = '" + _directory + "', cmd = '" + fullcmd + "')";
- }
+
+ return "process(dir = '" + directory + "', cmd = '" + fullcmd + "')";
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
import java.io.IOException;
/**
* Input resource based on an input stream.
- *
+ *
* @author Erik Brakkee
*/
public class StreamResource implements InputResource {
/**
* Input stream to read.
*/
- private InputStream _stream;
+ private InputStream stream;
/**
* Constructs a resource.
* Input stream to read.
*/
public StreamResource(InputStream aStream) {
- _stream = aStream;
+ stream = aStream;
}
/*
* @see InputResource#getInputStream()
*/
public InputStream getInputStream() throws IOException {
- return _stream;
+ return stream;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.observer;
/**
* Default observer notifier which calls
* {@link org.wamblee.observer.Observer#send(ObservableType, Event)}
* immediately.
- *
+ *
* @author Erik Brakkee
*/
public class DefaultObserverNotifier<ObservableType, Event> implements
- ObserverNotifier<ObservableType, Event> {
-
+ ObserverNotifier<ObservableType, Event> {
/**
* Constructs the notifier.
*
/*
* (non-Javadoc)
*
- * @see org.wamblee.observer.ObserverNotifier#update(org.wamblee.observer.Observer,
- * ObservableType, Event)
+ * @see
+ * org.wamblee.observer.ObserverNotifier#update(org.wamblee.observer.Observer
+ * , ObservableType, Event)
*/
public void update(Observer<ObservableType, Event> aObserver,
- ObservableType aObservable, Event aEvent) {
+ ObservableType aObservable, Event aEvent) {
aObserver.send(aObservable, aEvent);
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.observer;
-import java.util.List;
+import org.apache.log4j.Logger;
+
import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
-import org.apache.log4j.Logger;
-
/**
* Implements subscription and notification logic for an observer pattern. This
* class is thread safe.
*/
public class Observable<ObservableType, Event> {
-
private static final Logger LOGGER = Logger.getLogger(Observable.class);
/**
* Observable.
*/
- private ObservableType _observable;
+ private ObservableType observable;
/**
* Used to notify observers.
*/
- private ObserverNotifier<ObservableType, Event> _notifier;
+ private ObserverNotifier<ObservableType, Event> notifier;
/**
* Map of subscription to observer.
*/
- private Map<Long, Observer<ObservableType, Event>> _observers;
+ private Map<Long, Observer<ObservableType, Event>> observers;
/**
* Counter for subscriptions. Holds the next subscription.
*/
- private long _counter;
+ private long counter;
/**
* Constructs the observable.
* Object used for implementing notification of listeners.
*/
public Observable(ObservableType aObservable,
- ObserverNotifier<ObservableType, Event> aNotifier) {
- _observable = aObservable;
- _notifier = aNotifier;
- _observers = new TreeMap<Long, Observer<ObservableType, Event>>();
- _counter = 0;
+ ObserverNotifier<ObservableType, Event> aNotifier) {
+ observable = aObservable;
+ notifier = aNotifier;
+ observers = new TreeMap<Long, Observer<ObservableType, Event>>();
+ counter = 0;
}
/**
* @return Event Event to send.
*/
public synchronized long subscribe(Observer<ObservableType, Event> aObserver) {
- long subscription = _counter++; // integer rage is so large it will
- // never roll over.
- _observers.put(subscription, aObserver);
+ long subscription = counter++; // integer rage is so large it will
+ // never roll over.
+
+ observers.put(subscription, aObserver);
+
return subscription;
}
* In case the subscription is not known.
*/
public synchronized void unsubscribe(long aSubscription) {
- Object obj = _observers.remove(aSubscription);
+ Object obj = observers.remove(aSubscription);
+
if (obj == null) {
- throw new IllegalArgumentException("Subscription '" + aSubscription
- + "'");
+ throw new IllegalArgumentException("Subscription '" +
+ aSubscription + "'");
}
}
* @return Number of subscribed observers.
*/
public int getObserverCount() {
- return _observers.size();
+ return observers.size();
}
/**
// Make sure we do the notification while not holding the lock to avoid
// potential deadlock
// situations.
- List<Observer<ObservableType, Event>> observers = new ArrayList<Observer<ObservableType, Event>>();
+ List<Observer<ObservableType, Event>> myObservers = new ArrayList<Observer<ObservableType, Event>>();
+
synchronized (this) {
- observers.addAll(_observers.values());
+ myObservers.addAll(observers.values());
}
- for (Observer<ObservableType, Event> observer : observers) {
- _notifier.update(observer, _observable, aEvent);
- }
- }
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable {
- if (_observers.size() > 0) {
- LOGGER
- .error("Still observers registered at finalization of observer!");
- for (Observer observer : _observers.values()) {
- LOGGER.error(" observer: " + observer);
- }
+ for (Observer<ObservableType, Event> observer : myObservers) {
+ notifier.update(observer, observable, aEvent);
}
-
- super.finalize();
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.observer;
/**
- * This is a type-safe version of {@link java.util.Observable}.
- *
+ * This is a type-safe version of {@link java.util.Observable}.
+ *
* @author Erik Brakkee
*/
public interface Observer<ObservableType, Event> {
-
/**
* Called when an event has occurred on the observable.
- * @param aObservable Observable.
- * @param aEvent Event.
+ *
+ * @param aObservable
+ * Observable.
+ * @param aEvent
+ * Event.
*/
- void send(ObservableType aObservable, Event aEvent);
+ void send(ObservableType aObservable, Event aEvent);
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.observer;
/**
- * Implementation of notification of subscribers.
- *
+ * Implementation of notification of subscribers.
+ *
* @author Erik Brakkee
*/
public interface ObserverNotifier<ObservableType, Event> {
-
/**
- * Notifies an observer.
- *
- * @param aObserver Observer to notify
- * @param aObservable Observable at which the event occured.
- * @param aEvent Event that occured.
+ * Notifies an observer.
+ *
+ * @param aObserver
+ * Observer to notify
+ * @param aObservable
+ * Observable at which the event occured.
+ * @param aEvent
+ * Event that occured.
*/
- void update(Observer<ObservableType, Event> aObserver, ObservableType aObservable, Event aEvent);
-
+ void update(Observer<ObservableType, Event> aObserver,
+ ObservableType aObservable, Event aEvent);
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.persistence;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.persistence.EntityManager;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wamblee.persistence.PersistentFactory.EntityAccessor;
+import org.wamblee.reflection.ReflectionUtils;
+
+/**
+ * Support for merging of JPA entities. This utility allows the result of a
+ * merge (modifications of primary key and/or version) to be merged back into
+ * the argument that was merged. As a result, the merged entity can be reused
+ * and the application is not forced to use the new version that was returned
+ * from the merge.
+ *
+ * The utility traverses the object graph based on the public getter methods.
+ * Therefore, care should be taken with this utility as usage could lead to
+ * recursively loading all objects reachable from the given object. Then again,
+ * this utility is for working with detached objects and it would, in general,
+ * be bad practice to work with detached objects that still contain unresolved
+ * lazy loaded relations and with detached objects that implicitly refer to
+ * almost the entire datamodel.
+ *
+ * This utility best supports a service oriented design where interaction is
+ * through service interfaces where each service has its own storage isolated
+ * from other services. That would be opposed to a shared data design with many
+ * services acting on the same data.
+ *
+ * @author Erik Brakkee
+ */
+public class JpaMergeSupport {
+ private static final Log LOG = LogFactory.getLog(JpaMergeSupport.class);
+
+ /**
+ * Constructs the object.
+ *
+ */
+ public JpaMergeSupport() {
+ // Empty
+ }
+
+ /**
+ * As {@link #merge(Persistent)} but with a given template. This method can
+ * be accessed in a static way.
+ *
+ * @param aMerge
+ * The result of the call to {@link EntityManager#merge(Object)}.
+ * @param aPersistent
+ * Object that was passed to {@link EntityManager#merge(Object)}.
+ */
+ public static void merge(Object aMerged, Object aPersistent) {
+ processPersistent(aMerged, aPersistent, new ArrayList<ObjectElem>());
+ }
+
+ /**
+ * Copies primary keys and version from the result of the merged to the
+ * object that was passed to the merge operation. It does this by traversing
+ * the public properties of the object. It copies the primary key and
+ * version for objects that implement {@link Persistent} and applies the
+ * same rules to objects in maps and sets as well (i.e. recursively).
+ *
+ * @param aPersistent
+ * Object whose primary key and version are to be set.
+ * @param aMerged
+ * Object that was the result of the merge.
+ * @param aProcessed
+ * List of already processed Persistent objects of the persistent
+ * part.
+ *
+ */
+ public static void processPersistent(Object aMerged, Object aPersistent,
+ List<ObjectElem> aProcessed) {
+ if ((aPersistent == null) && (aMerged == null)) {
+ return;
+ }
+
+ if ((aPersistent == null) || (aMerged == null)) {
+ throw new RuntimeException("persistent or merged object is null '" +
+ aPersistent + "'" + " '" + aMerged + "'");
+ }
+
+ ObjectElem elem = new ObjectElem(aPersistent);
+
+ if (aProcessed.contains(elem)) {
+ return; // already processed.
+ }
+
+ aProcessed.add(elem);
+
+ LOG.debug("Setting pk/version on " + aPersistent + " from " + aMerged);
+
+ Persistent persistentWrapper = PersistentFactory.create(aPersistent);
+ Persistent mergedWrapper = PersistentFactory.create(aMerged);
+
+ if (persistentWrapper == null) {
+ // Not an entity so it is ignored.
+ return;
+ }
+
+ Serializable pk = persistentWrapper.getPrimaryKey();
+ boolean pkIsNull = false;
+ if (pk instanceof Number) {
+ if (((Number) pk).longValue() != 0l) {
+ pkIsNull = false;
+ } else {
+ pkIsNull = true;
+ }
+ } else {
+ pkIsNull = (pk == null);
+ }
+ if (!pkIsNull &&
+ !mergedWrapper.getPrimaryKey().equals(
+ persistentWrapper.getPrimaryKey())) {
+ throw new IllegalArgumentException(
+ "Mismatch between primary key values: " + aPersistent + " " +
+ aMerged);
+ } else {
+ persistentWrapper.setPersistedVersion(mergedWrapper
+ .getPersistedVersion());
+ persistentWrapper.setPrimaryKey(mergedWrapper.getPrimaryKey());
+ }
+
+ List<Method> methods = ReflectionUtils.getAllMethods(aPersistent
+ .getClass(), Object.class);
+
+ for (Method getter : methods) {
+ if ((getter.getName().startsWith("get") || getter.getName()
+ .startsWith("is")) &&
+ !Modifier.isStatic(getter.getModifiers()) &&
+ Modifier.isPublic(getter.getModifiers()) &&
+ getter.getParameterTypes().length == 0 &&
+ getter.getReturnType() != Void.class) {
+ Class returnType = getter.getReturnType();
+
+ try {
+ if (Set.class.isAssignableFrom(returnType)) {
+ Set merged = (Set) getter.invoke(aMerged);
+ Set persistent = (Set) getter.invoke(aPersistent);
+ processSet(merged, persistent, aProcessed);
+ } else if (List.class.isAssignableFrom(returnType)) {
+ List merged = (List) getter.invoke(aMerged);
+ List persistent = (List) getter.invoke(aPersistent);
+ processList(merged, persistent, aProcessed);
+ } else if (Map.class.isAssignableFrom(returnType)) {
+ Map merged = (Map) getter.invoke(aMerged);
+ Map persistent = (Map) getter.invoke(aPersistent);
+ processMap(merged, persistent, aProcessed);
+ } else if (returnType.isArray()) {
+ Object[] merged = (Object[]) getter.invoke(aMerged);
+ Object[] persistent = (Object[]) getter
+ .invoke(aPersistent);
+ if (merged.length != persistent.length) {
+ throw new IllegalArgumentException(
+ "Array sizes differ " + merged.length + " " +
+ persistent.length);
+ }
+ for (int i = 0; i < persistent.length; i++) {
+ processPersistent(merged[i], persistent[i],
+ aProcessed);
+ }
+ } else {
+ Object merged = getter.invoke(aMerged);
+ Object persistent = getter.invoke(aPersistent);
+ processPersistent(merged, persistent, aProcessed);
+ }
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Process the persistent objects in the collections.
+ *
+ * @param aPersistent
+ * Collection in the original object.
+ * @param aMerged
+ * Collection as a result of the merge.
+ * @param aProcessed
+ * List of processed persistent objects.
+ *
+ */
+ public static void processList(List aMerged, List aPersistent,
+ List<ObjectElem> aProcessed) {
+ Object[] merged = aMerged.toArray();
+ Object[] persistent = aPersistent.toArray();
+
+ if (merged.length != persistent.length) {
+ throw new IllegalArgumentException("Array sizes differ " +
+ merged.length + " " + persistent.length);
+ }
+
+ for (int i = 0; i < merged.length; i++) {
+ assert merged[i].equals(persistent[i]);
+ processPersistent(merged[i], persistent[i], aProcessed);
+ }
+ }
+
+ /**
+ * Process the persistent objects in sets.
+ *
+ * @param aPersistent
+ * Collection in the original object.
+ * @param aMerged
+ * Collection as a result of the merge.
+ * @param aProcessed
+ * List of processed persistent objects.
+ *
+ */
+ public static void processSet(Set aMerged, Set aPersistent,
+ List<ObjectElem> aProcessed) {
+ if (aMerged.size() != aPersistent.size()) {
+ throw new IllegalArgumentException("Array sizes differ " +
+ aMerged.size() + " " + aPersistent.size());
+ }
+
+ for (Object merged : aMerged) {
+ // Find the object that equals the merged[i]
+ for (Object persistent : aPersistent) {
+ if (persistent.equals(merged)) {
+ processPersistent(merged, persistent, aProcessed);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Process the Map objects in the collections.
+ *
+ * @param aPersistent
+ * Collection in the original object.
+ * @param aMerged
+ * Collection as a result of the merge.
+ * @param aProcessed
+ * List of processed persistent objects.
+ *
+ */
+ public static <Key, Value> void processMap(Map<Key, Value> aMerged,
+ Map<Key, Value> aPersistent, List<ObjectElem> aProcessed) {
+ if (aMerged.size() != aPersistent.size()) {
+ throw new IllegalArgumentException("Sizes differ " +
+ aMerged.size() + " " + aPersistent.size());
+ }
+
+ Set<Entry<Key, Value>> entries = aMerged.entrySet();
+
+ for (Entry<Key, Value> entry : entries) {
+ Key key = entry.getKey();
+ if (!aPersistent.containsKey(key)) {
+ throw new IllegalArgumentException("Key '" + key +
+ "' not found");
+ }
+
+ Value mergedValue = entry.getValue();
+ Object persistentValue = aPersistent.get(key);
+
+ processPersistent(mergedValue, persistentValue, aProcessed);
+ }
+ }
+
+ /**
+ * This class provided an equality operation based on the object reference
+ * of the wrapped object. This is required because we cannto assume that the
+ * equals operation has any meaning for different types of persistent
+ * objects. This allows us to use the standard collection classes for
+ * detecting cyclic dependences and avoiding recursion.
+ */
+ private static final class ObjectElem {
+ private Object object;
+
+ public ObjectElem(Object aObject) {
+ object = aObject;
+ }
+
+ public boolean equals(Object aObj) {
+ if (aObj == null) {
+ return false;
+ }
+ if (!(aObj instanceof ObjectElem)) {
+ return false;
+ }
+ return ((ObjectElem) aObj).object == object;
+ }
+
+ public int hashCode() {
+ return object.hashCode();
+ }
+ }
+}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.persistence;
import java.io.Serializable;
/**
- * Interface for persistent objects. This defines required functionality for all objects
- * that are persisted.
+ * Interface for persistent objects. This defines required functionality for all
+ * objects that are persisted.
*
- * Objects that implement this interface and which implement
- * {@link java.lang.Object#equals(java.lang.Object)}
- * should exclude the primary key and version from determining equality.
+ * Objects that implement this interface and which implement
+ * {@link java.lang.Object#equals(java.lang.Object)} should exclude the primary
+ * key and version from determining equality.
*/
public interface Persistent {
-
/**
- * Gets the primary key.
+ * Gets the primary key.
+ *
* @return Primary key.
- * @see #setPrimaryKey(Serializable)
+ *
+ * @see #setPrimaryKey(Serializable)
*/
- Serializable getPrimaryKey();
-
+ Serializable getPrimaryKey();
+
/**
- * Sets the primary key.
- * @param aKey Primary key.
- * @see #getPrimaryKey()
+ * Sets the primary key.
+ *
+ * @param aKey
+ * Primary key.
+ *
+ * @see #getPrimaryKey()
*/
- void setPrimaryKey(Serializable aKey);
-
+ void setPrimaryKey(Serializable aKey);
+
/**
- * Gets the version.
- * @return Version.
+ * Gets the version.
+ *
+ * @return Version.
+ *
* @see #setPersistedVersion(int)
*/
- int getPersistedVersion();
-
+ Number getPersistedVersion();
+
/**
- * Sets the version.
- * @param aVersion Version.
+ * Sets the version.
+ *
+ * @param aVersion
+ * Version.
+ *
* @see #getPersistedVersion()
*/
- void setPersistedVersion(int aVersion);
+ void setPersistedVersion(Number aVersion);
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.persistence;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+import org.wamblee.reflection.ReflectionUtils;
+
+/**
+ * Factory which creates a {@link Persistent} object for a given entity for
+ * interfacing with the primary key and version of the entity.
+ *
+ * This utility only treats primary keys and fields that are annotated with @Id
+ * and @Version. In case ORM files are used for the definition of primary key
+ * and or version, then those fields are ignored.
+ *
+ * @author Erik Brakkee
+ *
+ */
+public class PersistentFactory {
+
+ /**
+ * Cache of a mapping of class names to entity accessors.
+ */
+ private static Map<String, EntityAccessor> CACHE = new ConcurrentHashMap<String, EntityAccessor>();
+
+ static interface Accessor<T> {
+ void set(Object aEntity, T aValue);
+
+ T get(Object aEntity);
+ }
+
+ static class FieldAccessor<T> implements Accessor<T> {
+ private Field field;
+
+ public FieldAccessor(Field aField) {
+ field = aField;
+ field.setAccessible(true);
+ }
+
+ @Override
+ public T get(Object aEntity) {
+ try {
+ T value = (T) field.get(aEntity);
+ return value;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void set(Object aEntity, T aValue) {
+ try {
+ field.set(aEntity, aValue);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ public Field getField() {
+ return field;
+ }
+ }
+
+ static class PropertyAccessor<T> implements Accessor<T> {
+ private Method getter;
+ private Method setter;
+
+ public PropertyAccessor(Method aGetter, Method aSetter) {
+ getter = aGetter;
+ setter = aSetter;
+ getter.setAccessible(true);
+ setter.setAccessible(true);
+ }
+
+ @Override
+ public T get(Object aEntity) {
+ try {
+ return (T) getter.invoke(aEntity);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void set(Object aEntity, T aValue) {
+ try {
+ setter.invoke(aEntity, aValue);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Method getGetter() {
+ return getter;
+ }
+
+ public Method getSetter() {
+ return setter;
+ }
+ }
+
+ static class EntityAccessor {
+ private Accessor pk;
+ private Accessor version;
+
+ public EntityAccessor(Accessor<?> aPk, Accessor<?> aVersion) {
+ pk = aPk;
+ version = aVersion;
+ }
+
+ public Accessor getPk() {
+ return pk;
+ }
+
+ public Accessor getVersion() {
+ return version;
+ }
+ }
+
+ public static class EntityObjectAccessor implements Persistent {
+ private EntityAccessor accessor;
+ private Object entity;
+
+ public EntityObjectAccessor(Object aEntity, EntityAccessor aAccessor) {
+ accessor = aAccessor;
+ entity = aEntity;
+ }
+
+ public EntityAccessor getAccessor() {
+ return accessor;
+ };
+
+ @Override
+ public Serializable getPrimaryKey() {
+ if (accessor == null || accessor.getPk() == null) {
+ return null;
+ }
+ return (Serializable) accessor.getPk().get(entity);
+ }
+
+ @Override
+ public void setPrimaryKey(Serializable aKey) {
+ if (accessor == null || accessor.getPk() == null) {
+ return;
+ }
+ accessor.getPk().set(entity, aKey);
+ }
+
+ @Override
+ public Number getPersistedVersion() {
+ if (accessor == null || accessor.getVersion() == null) {
+ return null;
+ }
+ return (Number) accessor.getVersion().get(entity);
+ }
+
+ @Override
+ public void setPersistedVersion(Number aVersion) {
+ if (accessor == null || accessor.getVersion() == null) {
+ return;
+ }
+ accessor.getVersion().set(entity, aVersion);
+ }
+ }
+
+ /**
+ * Create the entity accessor for a given class or returns a cached instance
+ * if one already exists.
+ *
+ * @param aClass
+ * Class.
+ * @return Entity accessor for the given class or null of the given object
+ * is not an entity.
+ */
+ public static EntityAccessor createEntityAccessor(Class aClass) {
+ EntityAccessor accessor = CACHE.get(aClass.getName());
+ if (accessor == null) {
+ accessor = analyse(aClass);
+ if (accessor != null) {
+ CACHE.put(aClass.getName(), accessor);
+ }
+ }
+ return accessor;
+ }
+
+ private static EntityAccessor analyse(Class aClass) {
+ Accessor<Serializable> pk = analyse(aClass, Id.class);
+ Accessor<Integer> version = analyse(aClass, Version.class);
+ if (pk != null || version != null) {
+ return new EntityAccessor(pk, version);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the accessor for a given annotation.
+ *
+ * @param aClass
+ * Class to analyse.
+ * @param aAnnotation
+ * Annotation that must be present.
+ * @return Accessor to use or null if the annotation is not present.
+ */
+ private static Accessor analyse(Class aClass,
+ Class<? extends Annotation> aAnnotation) {
+ List<Field> fields = ReflectionUtils.getAllFields(aClass);
+ for (Field field : fields) {
+ if (field.isAnnotationPresent(aAnnotation)) {
+ return new FieldAccessor(field);
+ }
+ }
+ List<Method> methods = ReflectionUtils.getAllMethods(aClass,
+ Object.class);
+ for (Method method : methods) {
+ if (method.isAnnotationPresent(aAnnotation)) {
+ String setterName = null;
+ if (method.getName().startsWith("get")) {
+ setterName = method.getName().replaceFirst("get", "set");
+ } else if (method.getName().startsWith("is")) {
+ setterName = method.getName().replaceFirst("is", "set");
+ }
+ try {
+ Class returnType = method.getReturnType();
+ Method setter = method.getDeclaringClass()
+ .getDeclaredMethod(setterName, returnType);
+ return new PropertyAccessor(method, setter);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Error obtaining setter for " +
+ method.getName() + " in class " + aClass.getName(), e);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates the {@link Persistent} wrapper for interfacing with primary key
+ * and version of the entity.
+ *
+ * @param aEntity
+ * Entity to use.
+ * @return Persistent object or null if this is not an entity.
+ */
+ public static Persistent create(Object aEntity) {
+ EntityAccessor accessor = createEntityAccessor(aEntity.getClass());
+ if (accessor == null) {
+ return null;
+ }
+ return new EntityObjectAccessor(aEntity, accessor);
+ }
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.reflection;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
public class ReflectionUtils {
+ /**
+ * Wraps a type by the corresponding wrapper type if it is a primitive type.
+ *
+ * @param aClass
+ * Type to wrap.
+ * @return Wrapped type for primitives or the provided argument value.
+ */
+ public static Class wrapIfNeeded(Class aClass) {
+ if (aClass == boolean.class) {
+ return Boolean.class;
+ }
- /**
- * Wraps a type by the corresponding wrapper type if it is a primitive
- * type.
- * @param aClass Type to wrap.
- * @return Wrapped type for primitives or the provided argument value.
- */
- public static Class wrapIfNeeded(Class aClass) {
-
- if (aClass == boolean.class) {
- return Boolean.class;
- }
- if (aClass == byte.class) {
- return Byte.class;
- }
- if (aClass == char.class) {
- return Character.class;
- }
- if (aClass == short.class) {
- return Short.class;
- }
- if (aClass == int.class) {
- return Integer.class;
- }
- if (aClass == long.class) {
- return Long.class;
- }
- if (aClass == float.class) {
- return Float.class;
- }
- if (aClass == double.class) {
- return Double.class;
- }
- if (aClass == void.class) {
- return Void.class;
- }
- return aClass;
- }
-
-
- public static List<Method> getAllMethods(Class aClass) {
-
- Map<String,Method> found = new HashMap<String, Method>();
- getAllMethods(aClass, found);
- return new ArrayList<Method>(found.values());
- }
-
- private static void getAllMethods(Class aClass, Map<String,Method> aFound) {
- List<Method> declared = Arrays.asList(aClass.getDeclaredMethods());
- for (Method method: declared) {
- Method superMethod = aFound.get(method.getName());
- if ( superMethod == null ) {
- // no superclass method
- aFound.put(method.getName(), method);
- }
- else {
- // super class method. Check for override.
- if ( !Arrays.equals(superMethod.getParameterTypes(), method.getParameterTypes())) {
- // parameters differ so this is a new method.
- aFound.put(method.getName(), method);
- }
- }
- }
- Class superClass = aClass.getSuperclass();
- if (superClass != null) {
- getAllMethods(superClass, aFound);
- }
- }
+ if (aClass == byte.class) {
+ return Byte.class;
+ }
+
+ if (aClass == char.class) {
+ return Character.class;
+ }
+
+ if (aClass == short.class) {
+ return Short.class;
+ }
+
+ if (aClass == int.class) {
+ return Integer.class;
+ }
+
+ if (aClass == long.class) {
+ return Long.class;
+ }
+
+ if (aClass == float.class) {
+ return Float.class;
+ }
+
+ if (aClass == double.class) {
+ return Double.class;
+ }
+
+ if (aClass == void.class) {
+ return Void.class;
+ }
+
+ return aClass;
+ }
+
+ public static List<Method> getAllMethods(Class aClass,
+ Class... aExcludedClasses) {
+ if (aClass.isInterface()) {
+ throw new IllegalArgumentException(aClass.getName() +
+ " is not an interface.");
+ }
+ Map<String, Method> found = new HashMap<String, Method>();
+ getAllMethods(aClass, found, Arrays.asList(aExcludedClasses));
+
+ return new ArrayList<Method>(found.values());
+ }
+
+ private static void getAllMethods(Class aClass, Map<String, Method> aFound,
+ List<Class> aExcludedClasses) {
+ List<Method> declared = Arrays.asList(aClass.getDeclaredMethods());
+
+ for (Method method : declared) {
+ Method superMethod = aFound.get(method.getName());
+
+ if (superMethod == null) {
+ // no subclass method
+ aFound.put(method.getName(), method);
+ } else {
+ // subclass method. Check for override.
+ if (!Arrays.equals(superMethod.getParameterTypes(), method
+ .getParameterTypes())) {
+ // parameters differ so this is a new method.
+ aFound.put(method.getName(), method);
+ }
+ }
+ }
+
+ Class superClass = aClass.getSuperclass();
+
+ if (superClass != null && !aExcludedClasses.contains(superClass)) {
+ getAllMethods(superClass, aFound, aExcludedClasses);
+ }
+ }
+
+ public static List<Field> getAllFields(Class aClass,
+ Class... aExcludedClasses) {
+ if (aClass.isInterface()) {
+ throw new IllegalArgumentException(aClass.getName() +
+ " is an interface.");
+ }
+ List<Field> found = new ArrayList<Field>();
+ getAllFields(aClass, found, Arrays.asList(aExcludedClasses));
+
+ return found;
+ }
+
+ private static void getAllFields(Class aClass, List<Field> aFound,
+ List<Class> aExcludedClasses) {
+ List<Field> declared = Arrays.asList(aClass.getDeclaredFields());
+
+ for (Field field : declared) {
+ aFound.add(field);
+ }
+
+ Class superClass = aClass.getSuperclass();
+
+ if (superClass != null && !aExcludedClasses.contains(superClass)) {
+ getAllFields(superClass, aFound, aExcludedClasses);
+ }
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.xml;
+import org.wamblee.io.ClassPathResource;
+import org.wamblee.io.InputResource;
+
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
-import org.wamblee.io.ClassPathResource;
-import org.wamblee.io.InputResource;
-
/**
* URI resolver that resolves stylesheets through the classpath.
*/
public class ClasspathUriResolver implements URIResolver {
-
/**
* Constructs the resolver.
*
* (non-Javadoc)
*
* @see javax.xml.transform.URIResolver#resolve(java.lang.String,
- * java.lang.String)
+ * java.lang.String)
*/
public Source resolve(String aHref, String aBase)
- throws TransformerException {
+ throws TransformerException {
InputResource xslt = new ClassPathResource(aHref);
+
try {
return new StreamSource(xslt.getInputStream());
} catch (IOException e) {
throw new TransformerException(
- "Could not get XSLT style sheet in classpath '" + aHref
- + "'", e);
+ "Could not get XSLT style sheet in classpath '" + aHref + "'",
+ e);
}
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.xml;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
+
+import org.dom4j.DocumentException;
+
+import org.dom4j.io.DOMReader;
+import org.dom4j.io.DOMWriter;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.xml.sax.SAXException;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.xml.serialize.OutputFormat;
-import org.apache.xml.serialize.XMLSerializer;
-import org.dom4j.DocumentException;
-import org.dom4j.io.DOMReader;
-import org.dom4j.io.DOMWriter;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
/**
* Some basic XML utilities for common reoccuring tasks for DOM documents.
- *
+ *
* @author Erik Brakkee
*/
public final class DomUtils {
-
private static final Log LOG = LogFactory.getLog(DomUtils.class);
/**
*
* @param aDocument
* document.
+ *
* @return
+ *
*/
public static Document read(String aDocument) throws XMLException {
ByteArrayInputStream is = new ByteArrayInputStream(aDocument.getBytes());
+
return read(is);
}
*
* @param aIs
* Input stream.
+ *
* @return
+ *
*/
public static Document read(InputStream aIs) throws XMLException {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
- .newDocumentBuilder();
+ .newDocumentBuilder();
+
return builder.parse(aIs);
- } catch (SAXException e) {
+ } catch (SAXException e) {
throw new XMLException(e.getMessage(), e);
} catch (IOException e) {
throw new XMLException(e.getMessage(), e);
* Input stream.
* @param aSchema
* Schema.
+ *
* @return Parsed and validated document.
+ *
*/
public static Document readAndValidate(InputStream aIs, InputStream aSchema)
- throws XMLException {
-
+ throws XMLException {
try {
final Schema schema = SchemaFactory.newInstance(
- XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
- new StreamSource(aSchema));
+ XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
+ new StreamSource(aSchema));
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ final DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setSchema(schema);
} catch (Exception e) {
LOG.warn("Error closing schema", e);
}
+
try {
aIs.close();
} catch (Exception e) {
LOG.warn("Error closing XML file", e);
}
}
-
}
/**
* Document to serialize.
* @param aOs
* Output stream.
+ *
*/
public static void serialize(Document aDocument, OutputStream aOs)
- throws IOException {
+ throws IOException {
XMLSerializer serializer = new XMLSerializer(aOs, new OutputFormat());
serializer.serialize(aDocument);
}
*
* @param aDocument
* Document to serialize.
+ *
* @return Serialized document.
+ *
*/
public static String serialize(Document aDocument) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
serialize(aDocument, os);
+
return os.toString();
}
*
* @param aDocument
* Document to convert.
+ *
* @return W3C DOM document.
+ *
*/
public static Document convert(org.dom4j.Document aDocument)
- throws DocumentException {
+ throws DocumentException {
return new DOMWriter().write(aDocument);
}
*
* @param aDocument
* Document to convert.
+ *
* @return Dom4j document.
*/
public static org.dom4j.Document convert(Document aDocument) {
*/
public static void removeDuplicateAttributes(Node aNode) {
NodeList list = aNode.getChildNodes();
+
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
+
if (node instanceof Element) {
removeDuplicateAttributes((Element) node);
removeDuplicateAttributes(node);
NamedNodeMap attributes = aElement.getAttributes();
Map<String, Attr> uniqueAttributes = new TreeMap<String, Attr>();
List<Attr> attlist = new ArrayList<Attr>();
+
for (int i = 0; i < attributes.getLength(); i++) {
Attr attribute = (Attr) attributes.item(i);
+
if (uniqueAttributes.containsKey(attribute.getNodeName())) {
- LOG.info("Detected duplicate attribute (will be removed)'"
- + attribute.getNodeName() + "'");
+ LOG.info("Detected duplicate attribute (will be removed)'" +
+ attribute.getNodeName() + "'");
}
+
uniqueAttributes.put(attribute.getNodeName(), attribute);
attlist.add(attribute);
}
+
// Remove all attributes from the element.
for (Attr att : attlist) {
aElement.removeAttributeNode(att);
}
+
// Add the unique attributes back to the element.
for (Attr att : uniqueAttributes.values()) {
aElement.setAttributeNode(att);
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.xml;
/**
- * Exception thrown in case of XML parsing problems.
- *
+ * Exception thrown in case of XML parsing problems.
+ *
* @author Erik Brakkee
*/
public class XMLException extends Exception {
-
- public XMLException(String aMsg) {
- super(aMsg);
+ /**
+ * Creates a new XMLException object.
+ *
+ */
+ public XMLException(String aMsg) {
+ super(aMsg);
}
-
- public XMLException(String aMsg, Throwable aCause) {
+
+ /**
+ * Creates a new XMLException object.
+ *
+ */
+ public XMLException(String aMsg, Throwable aCause) {
super(aMsg, aCause);
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
- * Licensed 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
+ * Licensed 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
+ * 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.
- */
-
+ * 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.wamblee.xml;
+import org.w3c.dom.Document;
+
+import org.wamblee.io.FileResource;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
-import org.w3c.dom.Document;
-import org.wamblee.io.FileResource;
-
/**
* XSL transformer for simplified usage of XSL transformations.
- *
+ *
* @author Erik Brakkee
*/
public class XslTransformer {
-
- private TransformerFactory _factory;
+ private TransformerFactory factory;
/**
* Constructs the URL resolver.
* URI resolver to use.
*/
public XslTransformer(URIResolver aResolver) {
- _factory = TransformerFactory.newInstance();
- _factory.setURIResolver(aResolver);
+ factory = TransformerFactory.newInstance();
+ factory.setURIResolver(aResolver);
}
/**
*
*/
public XslTransformer() {
- _factory = TransformerFactory.newInstance();
+ factory = TransformerFactory.newInstance();
}
/**
- * Resolves an XSLT based on URI.
- * @param aXslt XSLT to resolve,
+ * Resolves an XSLT based on URI.
+ *
+ * @param aXslt
+ * XSLT to resolve,
+ *
* @return Source for the XSLT
- * @throws TransformerException In case the XSLT cannot be found.
+ *
+ * @throws TransformerException
+ * In case the XSLT cannot be found.
*/
public Source resolve(String aXslt) throws TransformerException {
- URIResolver resolver = _factory.getURIResolver();
+ URIResolver resolver = factory.getURIResolver();
+
if (resolver == null) {
if (new File(aXslt).canRead()) {
try {
return new StreamSource(new FileResource(new File(aXslt))
- .getInputStream());
+ .getInputStream());
} catch (IOException e) {
throw new TransformerException(e.getMessage(), e);
}
} else {
- throw new TransformerException("Cannot read '" + aXslt + "'");
+ throw new TransformerException("Cannot read '" + aXslt + "'");
}
}
+
return resolver.resolve(aXslt, "");
}
* Document to transform.
* @param aXslt
* XSLT to use.
+ *
* @return Transformed document.
+ *
* @throws IOException
* In case of problems reading resources.
* @throws TransformerException
* In case transformation fails.
*/
public Document transform(Document aDocument, Source aXslt)
- throws IOException, TransformerException {
+ throws IOException, TransformerException {
Source source = new DOMSource(aDocument);
DOMResult result = new DOMResult();
transform(source, result, aXslt);
+
return (Document) result.getNode();
}
* Document to transform.
* @param aXslt
* XSLT to use.
+ *
* @return Transformed document.
+ *
* @throws IOException
* In case of problems reading resources.
* @throws TransformerException
* In case transformation fails.
*/
public Document transform(byte[] aDocument, Source aXslt)
- throws IOException, TransformerException {
+ throws IOException, TransformerException {
Source source = new StreamSource(new ByteArrayInputStream(aDocument));
DOMResult result = new DOMResult();
transform(source, result, aXslt);
+
return (Document) result.getNode();
}
* Document to transform.
* @param aXslt
* XSL transformation.
+ *
* @return Transformed document.
+ *
*/
public String textTransform(byte[] aDocument, Source aXslt)
- throws IOException, TransformerException {
+ throws IOException, TransformerException {
Source source = new StreamSource(new ByteArrayInputStream(aDocument));
ByteArrayOutputStream os = new ByteArrayOutputStream();
StreamResult result = new StreamResult(os);
transform(source, result, aXslt);
+
return new String(os.toByteArray());
}
* Result of the transformation.
* @param aXslt
* XSLT to use.
+ *
* @throws IOException
* In case of problems reading resources.
* @throws TransformerException
* In case transformation fails.
*/
public void transform(Source aSource, Result aResult, Source aXslt)
- throws IOException, TransformerException {
+ throws IOException, TransformerException {
try {
- Transformer transformer = _factory.newTransformer(aXslt);
+ Transformer transformer = factory.newTransformer(aXslt);
transformer.transform(aSource, aResult);
} catch (TransformerConfigurationException e) {
throw new TransformerException(
- "Configuration problem of XSLT transformation", e);
+ "Configuration problem of XSLT transformation", e);
}
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.cache;
-import java.io.IOException;
-
import junit.framework.TestCase;
+
import net.sf.ehcache.CacheException;
import org.wamblee.io.TestResource;
+
import org.wamblee.test.TimingUtils;
+import java.io.IOException;
+
/**
- * Cached object test.
- *
+ * Cached object test.
+ *
* @author Erik Brakkee
*/
public class CachedObjectTest extends TestCase {
-
- /**
- *
- */
private static final String EHCACHE_CONFIG = "ehcache.xml";
+ private static final int OBJECT_KEY = 10;
+ private CachedObject.Computation<Integer, Integer> computation;
+ private int ncomputations;
- private static final int OBJECT_KEY = 10;
-
- private CachedObject.Computation<Integer,Integer> _computation;
- private int _ncomputations;
-
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
super.setUp();
- _computation = new CachedObject.Computation<Integer,Integer>() {
+ computation = new CachedObject.Computation<Integer, Integer>() {
public Integer getObject(Integer aObjectKey) {
- _ncomputations++;
+ ncomputations++;
+
return compute(aObjectKey);
};
};
- _ncomputations = 0;
+ ncomputations = 0;
}
-
- private int compute(int aValue) {
+
+ private int compute(int aValue) {
return aValue + 10;
}
-
- private CachedObject<Integer, Integer> createCached(Cache<Integer,Integer> aCache) {
- return new CachedObject<Integer, Integer>(aCache, OBJECT_KEY, _computation);
+
+ private CachedObject<Integer, Integer> createCached(
+ Cache<Integer, Integer> aCache) {
+ return new CachedObject<Integer, Integer>(aCache, OBJECT_KEY,
+ computation);
}
/**
- * Verifies that upon first use, the cached object uses the computation to
- * retrieve the object.
- *
+ * Verifies that upon first use, the cached object uses the computation to
+ * retrieve the object.
+ *
*/
- public void testComputation() {
- CachedObject<Integer, Integer> cached = createCached(new ZeroCache<Integer,Integer>());
+ public void testComputation() {
+ CachedObject<Integer, Integer> cached = createCached(new ZeroCache<Integer, Integer>());
int value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
+ assertEquals(1, ncomputations);
}
-
- public void testInvalidateCache() {
- CachedObject<Integer, Integer> cached = createCached(new ForeverCache<Integer,Integer>());
+
+ public void testInvalidateCache() {
+ CachedObject<Integer, Integer> cached = createCached(new ForeverCache<Integer, Integer>());
int value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
- cached.invalidate();
+ assertEquals(1, ncomputations);
+ cached.invalidate();
value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(2, _ncomputations);
+ assertEquals(2, ncomputations);
}
-
+
public void testBehaviorEhCache() throws CacheException, IOException {
- Cache<Integer,Integer> cache = new EhCache<Integer,Integer>(new TestResource(CachedObjectTest.class, EHCACHE_CONFIG), "test");
+ Cache<Integer, Integer> cache = new EhCache<Integer, Integer>(
+ new TestResource(CachedObjectTest.class, EHCACHE_CONFIG), "test");
CachedObject<Integer, Integer> cached = createCached(cache);
-
- assertTrue( cache == cached.getCache());
+
+ assertTrue(cache == cached.getCache());
+
int value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
- // The value must still be cached.
- value = cached.get();
+ assertEquals(1, ncomputations);
+ // The value must still be cached.
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
-
- // Cache expiry.
- TimingUtils.sleep(6000);
- value = cached.get();
+ assertEquals(1, ncomputations);
+
+ // Cache expiry.
+ TimingUtils.sleep(6000);
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(2, _ncomputations);
-
+ assertEquals(2, ncomputations);
+
// Should still be cached now.
- value = cached.get();
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(2, _ncomputations);
-
+ assertEquals(2, ncomputations);
+
// explicit invalidation.
- cached.invalidate();
- value = cached.get();
+ cached.invalidate();
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(3, _ncomputations);
-
+ assertEquals(3, ncomputations);
}
-
+
public void testBehaviorEhCacheDefault() throws CacheException, IOException {
- Cache<Integer,Integer> cache = new EhCache<Integer,Integer>(new TestResource(CachedObjectTest.class, EHCACHE_CONFIG), "undefined");
+ Cache<Integer, Integer> cache = new EhCache<Integer, Integer>(
+ new TestResource(CachedObjectTest.class, EHCACHE_CONFIG),
+ "undefined");
CachedObject<Integer, Integer> cached = createCached(cache);
-
- assertTrue( cache == cached.getCache());
+
+ assertTrue(cache == cached.getCache());
+
int value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
- // The value must still be cached.
- value = cached.get();
+ assertEquals(1, ncomputations);
+ // The value must still be cached.
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
-
- // Cache expiry.
- TimingUtils.sleep(6000);
- value = cached.get();
+ assertEquals(1, ncomputations);
+
+ // Cache expiry.
+ TimingUtils.sleep(6000);
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(2, _ncomputations);
-
+ assertEquals(2, ncomputations);
+
// Should still be cached now.
- value = cached.get();
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(2, _ncomputations);
-
+ assertEquals(2, ncomputations);
}
-
-
- public void testBehaviorForeverCache() {
- CachedObject<Integer, Integer> cached = createCached(new ForeverCache<Integer,Integer>());
+
+ public void testBehaviorForeverCache() {
+ CachedObject<Integer, Integer> cached = createCached(new ForeverCache<Integer, Integer>());
int value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
- for (int ncomp = 2; ncomp <= 100; ncomp++) {
- value = cached.get();
+ assertEquals(1, ncomputations);
+
+ for (int ncomp = 2; ncomp <= 100; ncomp++) {
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
+ assertEquals(1, ncomputations);
}
}
-
- public void testBehaviorZeroCache() {
- CachedObject<Integer, Integer> cached = createCached(new ZeroCache<Integer,Integer>());
+
+ public void testBehaviorZeroCache() {
+ CachedObject<Integer, Integer> cached = createCached(new ZeroCache<Integer, Integer>());
int value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(1, _ncomputations);
- for (int ncomp = 2; ncomp <= 100; ncomp++) {
- value = cached.get();
+ assertEquals(1, ncomputations);
+
+ for (int ncomp = 2; ncomp <= 100; ncomp++) {
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(ncomp, _ncomputations);
+ assertEquals(ncomp, ncomputations);
}
- cached.invalidate();
- value = cached.get();
+
+ cached.invalidate();
+ value = cached.get();
assertEquals(compute(OBJECT_KEY), value);
- assertEquals(101, _ncomputations);
+ assertEquals(101, ncomputations);
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.collections;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import junit.framework.TestCase;
import org.wamblee.conditions.Condition;
+
import org.wamblee.test.AssertionUtils;
-import junit.framework.TestCase;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
public class CollectionFilterTest extends TestCase {
-
- public void testFilter() {
- List<String> list = Arrays.asList(new String[] { "x", "y", "z", "y" });
- List<String> result = new ArrayList<String>();
- CollectionFilter.filter(list, result,
- new Condition<String>() {
- @Override
- public boolean matches(String aObject) {
- return aObject.equals("y");
- }
- });
- AssertionUtils.assertEquals(new String[] { "y", "y" }, result.toArray());
- }
-
+ public void testFilter() {
+ List<String> list = Arrays.asList(new String[] { "x", "y", "z", "y" });
+ List<String> result = new ArrayList<String>();
+ CollectionFilter.filter(list, result, new Condition<String>() {
+ @Override
+ public boolean matches(String aObject) {
+ return aObject.equals("y");
+ }
+ });
+ AssertionUtils
+ .assertEquals(new String[] { "y", "y" }, result.toArray());
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.concurrency;
+import junit.framework.TestCase;
+
import org.wamblee.test.EventTracker;
import org.wamblee.test.TimingUtils;
-import junit.framework.TestCase;
-
/**
* Tests for the JVMLock.
- *
+ *
* @author Erik Brakkee
*/
public abstract class AbstractLockTestCase extends TestCase {
-
protected static final int SLEEP_TIME = 1000;
-
protected static final String STARTED = "started";
-
protected static final String ACQUIRED = "acquired";
-
protected static final String RELEASED = "released";
-
- private EventTracker<String> _tracker;
+ private EventTracker<String> tracker;
/*
* (non-Javadoc)
*/
@Override
protected void setUp() throws Exception {
- _tracker = new EventTracker<String>();
+ tracker = new EventTracker<String>();
}
-
- protected EventTracker<String> getTracker() {
- return _tracker;
+
+ protected EventTracker<String> getTracker() {
+ return tracker;
}
/**
- * Must be implemented to generate the events
- * {@link #STARTED}, {@link #ACQUIRED}, and {@link #RELEASED} in
- * that order. The lock should be acquired for
- * the time specified by {@link #SLEEP_TIME}.
- * @return Thread which does the work.
+ * Must be implemented to generate the events {@link #STARTED},
+ * {@link #ACQUIRED}, and {@link #RELEASED} in that order. The lock should
+ * be acquired for the time specified by {@link #SLEEP_TIME}.
+ *
+ * @return Thread which does the work.
*/
protected abstract Thread runThread();
Thread t2 = runThread();
TimingUtils.sleep(SLEEP_TIME / 10); // give threads a chance to start
// up.
- assertEquals(2, _tracker.getEventCount(STARTED)); // both threads
+
+ assertEquals(2, tracker.getEventCount(STARTED)); // both threads
// should have
// started.
- assertEquals(1, _tracker.getEventCount(ACQUIRED)); // one thread has
- // acquired the
- // lock.
+
+ assertEquals(1, tracker.getEventCount(ACQUIRED)); // one thread has
+ // acquired the
+ // lock.
+
TimingUtils.sleep(SLEEP_TIME);
- assertEquals(2, _tracker.getEventCount(ACQUIRED)); // now the other
- // thread could also
- // acquire the lock
- assertEquals(1, _tracker.getEventCount(RELEASED)); // and the first
- // thread has
- // released it.
+ assertEquals(2, tracker.getEventCount(ACQUIRED)); // now the other
+ // thread could also
+ // acquire the lock
+
+ assertEquals(1, tracker.getEventCount(RELEASED)); // and the first
+ // thread has
+ // released it.
+
TimingUtils.sleep(SLEEP_TIME);
- assertEquals(2, _tracker.getEventCount(RELEASED)); // both threads
- // should be
- // finished.
+ assertEquals(2, tracker.getEventCount(RELEASED)); // both threads
+ // should be
+ // finished.
+
t1.join();
t2.join();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.concurrency;
import org.wamblee.test.TimingUtils;
/**
* Tests for the JVMLock.
- *
+ *
* @author Erik Brakkee
*/
public class JvmLockTest extends AbstractLockTestCase {
+ private JvmLock lock;
- private JvmLock _lock;
-
/*
* (non-Javadoc)
*
@Override
protected void setUp() throws Exception {
super.setUp();
- _lock = new JvmLock();
+ lock = new JvmLock();
}
protected Thread runThread() {
Thread t = new Thread(new Runnable() {
public void run() {
getTracker().eventOccurred(STARTED);
- _lock.acquire();
+ lock.acquire();
getTracker().eventOccurred(ACQUIRED);
TimingUtils.sleep(SLEEP_TIME);
- _lock.release();
+ lock.release();
getTracker().eventOccurred(RELEASED);
};
});
t.start();
+
return t;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.concurrency;
-import junit.framework.Assert;
import junit.framework.TestCase;
-
/**
* Testing the read-write lock class. Note: in case of problems, test cases
* could hang.
- *
+ *
* @see ReadWriteLock
*/
public class ReadWriteLockTest extends TestCase {
- /**
- *
- */
private static final int HALF_SECOND = 500;
- /**
- *
- */
+
private static final int ONE_SECOND = 1000;
- /**
- *
- */
+
private static final int TWO_SECONDS = 2000;
- private ReadWriteLock _lock;
- private int _nReaders;
- private int _nWriters;
+ private ReadWriteLock lock;
+ private int nReaders;
+ private int nWriters;
/**
* Constructor for ReadWriteLockTest.
- *
+ *
* @param aName
*/
public ReadWriteLockTest(String aName) {
}
private synchronized int getReaderCount() {
- return _nReaders;
+ return nReaders;
}
private synchronized int getWriterCount() {
- return _nWriters;
+ return nWriters;
}
synchronized void incrementReaderCount() {
- _nReaders++;
+ nReaders++;
}
synchronized void incrementWriterCount() {
- _nWriters++;
+ nWriters++;
}
synchronized void decrementReaderCount() {
- _nReaders--;
+ nReaders--;
}
synchronized void decrementWriterCount() {
- _nWriters--;
+ nWriters--;
}
/*
*/
protected void setUp() throws Exception {
super.setUp();
- _lock = new ReadWriteLock();
+ lock = new ReadWriteLock();
}
/*
* @see TestCase#tearDown()
*/
protected void tearDown() throws Exception {
- _lock = null;
+ lock = null;
super.tearDown();
}
* Acquire and release a read lock.
*/
public void testRead() {
- _lock.acquireRead();
- _lock.releaseRead();
+ lock.acquireRead();
+ lock.releaseRead();
}
/**
* Acquire and release a write lock.
*/
public void testWrite() {
- _lock.acquireWrite();
- _lock.releaseWrite();
+ lock.acquireWrite();
+ lock.releaseWrite();
}
/**
* Verify concurrent access by multiple readers is possible.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testMultipleReaders() throws InterruptedException {
- Runnable runnable = new ReadLocker(_lock, this, TWO_SECONDS);
+ Runnable runnable = new ReadLocker(lock, this, TWO_SECONDS);
- Thread t1 = new Thread(runnable);
+ Thread t1 = new Thread(runnable);
t1.start();
Thread t2 = new Thread(runnable);
/**
* Verify that only one writer at a time can acquire the write lock.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testSingleWriter() throws InterruptedException {
- WriteLocker writer = new WriteLocker(_lock, this, ONE_SECOND);
- Thread t1 = new Thread(writer);
- Thread t2 = new Thread(writer);
+ WriteLocker writer = new WriteLocker(lock, this, ONE_SECOND);
+ Thread t1 = new Thread(writer);
+ Thread t2 = new Thread(writer);
t1.start();
t2.start();
/**
* Verify that multiple writers cannot acquire the write lock concurrently.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testMultipleWriters() throws InterruptedException {
- WriteLocker writer1 = new WriteLocker(_lock, this, HALF_SECOND + ONE_SECOND);
- WriteLocker writer2 = new WriteLocker(_lock, this, ONE_SECOND);
- Thread t1 = new Thread(writer1);
- Thread t2 = new Thread(writer2);
+ WriteLocker writer1 = new WriteLocker(lock, this, HALF_SECOND +
+ ONE_SECOND);
+ WriteLocker writer2 = new WriteLocker(lock, this, ONE_SECOND);
+ Thread t1 = new Thread(writer1);
+ Thread t2 = new Thread(writer2);
t1.start();
Thread.sleep(HALF_SECOND);
Thread.sleep(ONE_SECOND);
// at t = 2, the second writer still must have
- // a lock.
+ // a lock.
assertTrue(getWriterCount() == 1);
t1.join();
t2.join();
}
/**
- * Verify that after the first reader acquires a lock, a subsequent writer
+ * Verify that after the first reader acquires a lock, a subsequent writer
* can only acquire the lock after the reader has released it.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReadWrite1() throws InterruptedException {
- ReadLocker readLocker = new ReadLocker(_lock, this, TWO_SECONDS);
- Thread t1 = new Thread(readLocker);
- WriteLocker writeLocker = new WriteLocker(_lock, this, TWO_SECONDS);
- Thread t2 = new Thread(writeLocker);
+ ReadLocker readLocker = new ReadLocker(lock, this, TWO_SECONDS);
+ Thread t1 = new Thread(readLocker);
+ WriteLocker writeLocker = new WriteLocker(lock, this, TWO_SECONDS);
+ Thread t2 = new Thread(writeLocker);
t1.start(); // acquire read lock
Thread.sleep(HALF_SECOND);
Thread.sleep(HALF_SECOND);
// 1 second underway, reader still holding the
- // lock so write lock cannot be acquired.
+ // lock so write lock cannot be acquired.
assertTrue(getReaderCount() == 1);
assertTrue(getWriterCount() == 0);
Thread.sleep(ONE_SECOND + HALF_SECOND);
- // 2.5 seconds underway, read lock released and
- // write lock must be acquired.
+ // 2.5 seconds underway, read lock released and
+ // write lock must be acquired.
assertTrue("Wrong no. of readers: " + getReaderCount(),
getReaderCount() == 0);
assertTrue(getWriterCount() == 1);
/**
* Verify that when multiple readers have acquired a read lock, the writer
* can only acquire the lock after all readers have released it.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReadWrite2() throws InterruptedException {
- ReadLocker readLocker1 = new ReadLocker(_lock, this, TWO_SECONDS + HALF_SECOND);
- ReadLocker readLocker2 = new ReadLocker(_lock, this, TWO_SECONDS + HALF_SECOND);
- Thread t1 = new Thread(readLocker1);
- Thread t2 = new Thread(readLocker2);
- WriteLocker writeLocker = new WriteLocker(_lock, this, TWO_SECONDS);
- Thread t3 = new Thread(writeLocker);
+ ReadLocker readLocker1 = new ReadLocker(lock, this, TWO_SECONDS +
+ HALF_SECOND);
+ ReadLocker readLocker2 = new ReadLocker(lock, this, TWO_SECONDS +
+ HALF_SECOND);
+ Thread t1 = new Thread(readLocker1);
+ Thread t2 = new Thread(readLocker2);
+ WriteLocker writeLocker = new WriteLocker(lock, this, TWO_SECONDS);
+ Thread t3 = new Thread(writeLocker);
t1.start(); // acquire read lock [0, 2.5]
Thread.sleep(ONE_SECOND);
Thread.sleep(HALF_SECOND);
// t = 1.5
assertTrue(getReaderCount() == 2);
- t3.start(); // write lock
+ t3.start(); // write lock
Thread.sleep(HALF_SECOND);
- // 2 seconds,
+ // 2 seconds,
assertTrue(getReaderCount() == 2);
assertTrue(getWriterCount() == 0);
Thread.sleep(ONE_SECOND);
assertTrue(getWriterCount() == 0);
Thread.sleep(ONE_SECOND);
- // 4 seconds underway, write lock must have
- // been acquired.
+ // 4 seconds underway, write lock must have
+ // been acquired.
assertTrue(getReaderCount() == 0);
assertTrue(getWriterCount() == 1);
}
/**
- * Verify that after a writer acquires a lock, a subsequent reader can
- * only acquire the lock after the writer has released it.
- *
- * @throws InterruptedException May not occur.
+ * Verify that after a writer acquires a lock, a subsequent reader can only
+ * acquire the lock after the writer has released it.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReadWrite3() throws InterruptedException {
- ReadLocker readLocker = new ReadLocker(_lock, this, TWO_SECONDS);
- Thread t1 = new Thread(readLocker);
- WriteLocker writeLocker = new WriteLocker(_lock, this, TWO_SECONDS);
- Thread t2 = new Thread(writeLocker);
+ ReadLocker readLocker = new ReadLocker(lock, this, TWO_SECONDS);
+ Thread t1 = new Thread(readLocker);
+ WriteLocker writeLocker = new WriteLocker(lock, this, TWO_SECONDS);
+ Thread t2 = new Thread(writeLocker);
t2.start(); // acquire write lock
Thread.sleep(HALF_SECOND);
Thread.sleep(HALF_SECOND);
// 1 second underway, writer still holding the
- // lock so read lock cannot be acquired.
+ // lock so read lock cannot be acquired.
assertTrue(getWriterCount() == 1);
assertTrue(getReaderCount() == 0);
Thread.sleep(ONE_SECOND + HALF_SECOND);
- // 2.5 seconds underway, write lock released and
- // read lock must be acquired.
+ // 2.5 seconds underway, write lock released and
+ // read lock must be acquired.
assertTrue("Wrong no. of writers: " + getReaderCount(),
getWriterCount() == 0);
assertTrue(getReaderCount() == 1);
}
/*
- * The following test cases are for testing whether or not
- * the read write lock checks the locking correctly.
- * Strictly speaking, these checks wouldn't be necessary
- * because it involves the contract of the ReadWriteLock which
- * must be obeyed by users of the ReadWriteLock. Nevertheless,
- * this is tested anyway to be absolutely sure.
+ * The following test cases are for testing whether or not the read write
+ * lock checks the locking correctly. Strictly speaking, these checks
+ * wouldn't be necessary because it involves the contract of the
+ * ReadWriteLock which must be obeyed by users of the ReadWriteLock.
+ * Nevertheless, this is tested anyway to be absolutely sure.
*/
/**
- * Acquire a read lock from one thread, release it from another. Verify
- * that a RuntimeException is thrown.
- *
- * @throws InterruptedException May not occur.
+ * Acquire a read lock from one thread, release it from another. Verify that
+ * a RuntimeException is thrown.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReleaseReadFromWrongThread() throws InterruptedException {
Thread t1 = null;
try {
t1 = new Thread(new Runnable() {
- public void run() {
- ReadWriteLockTest.this._lock.acquireRead();
- }
- });
+ public void run() {
+ ReadWriteLockTest.this.lock.acquireRead();
+ }
+ });
t1.start();
Thread.sleep(ONE_SECOND); // wait until thread is started
- _lock.releaseRead(); // release lock from wrong thread.
+ lock.releaseRead(); // release lock from wrong thread.
} catch (RuntimeException e) {
return; // ok
} finally {
/**
* Acquire a write lock from one thread, release it from another. Verify
* that a RuntimeException is thrown.
- *
- * @throws InterruptedException May not occur.
+ *
+ * @throws InterruptedException
+ * May not occur.
*/
public void testReleaseWriteFromWrongThread() throws InterruptedException {
Thread t1 = null;
try {
t1 = new Thread(new Runnable() {
- public void run() {
- ReadWriteLockTest.this._lock.acquireWrite();
- }
- });
+ public void run() {
+ ReadWriteLockTest.this.lock.acquireWrite();
+ }
+ });
t1.start();
Thread.sleep(ONE_SECOND); // wait until thread is started
- _lock.releaseWrite(); // release lock from wrong thread.
+ lock.releaseWrite(); // release lock from wrong thread.
} catch (RuntimeException e) {
return; // ok
} finally {
}
/**
- * Try to acquire a read lock multiple times. Verify that a
- * RuntimeException is thrown.
+ * Try to acquire a read lock multiple times. Verify that a RuntimeException
+ * is thrown.
*/
public void testAcquireReadTwice() {
try {
- _lock.acquireRead();
- _lock.acquireRead();
+ lock.acquireRead();
+ lock.acquireRead();
} catch (RuntimeException e) {
// ok
return;
*/
public void testAcquireWriteTwice() {
try {
- _lock.acquireWrite();
- _lock.acquireWrite();
+ lock.acquireWrite();
+ lock.acquireWrite();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireReadFollowedByWrite() {
try {
- _lock.acquireRead();
- _lock.acquireWrite();
+ lock.acquireRead();
+ lock.acquireWrite();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireWriteFollowedByRead() {
try {
- _lock.acquireWrite();
- _lock.acquireRead();
+ lock.acquireWrite();
+ lock.acquireRead();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireReadFollowedByReleaseaWrite() {
try {
- _lock.acquireRead();
- _lock.releaseWrite();
+ lock.acquireRead();
+ lock.releaseWrite();
} catch (RuntimeException e) {
return; // ok
}
*/
public void testAcquireWriteFollowedByReleaseRead() {
try {
- _lock.acquireWrite();
- _lock.releaseRead();
+ lock.acquireWrite();
+ lock.releaseRead();
} catch (RuntimeException e) {
return; // ok
}
}
}
-
/**
- * ReadLocker acquires a read lock and performs a callback when the lock as
- * been acquired, sleeps for a designated amount of time, releases the read
- * lock, and performs a callback after the lock has been released.
+ * ReadLocker acquires a read lock and performs a callback when the lock as been
+ * acquired, sleeps for a designated amount of time, releases the read lock, and
+ * performs a callback after the lock has been released.
*/
class ReadLocker implements Runnable {
- private ReadWriteLock _lock;
- private ReadWriteLockTest _lockTest;
- private int _sleepTime;
+ private ReadWriteLock lock;
+ private ReadWriteLockTest lockTest;
+ private int sleepTime;
public ReadLocker(ReadWriteLock aLock, ReadWriteLockTest aLockTest,
int aSleepTime) {
- _lock = aLock;
- _lockTest = aLockTest;
- _sleepTime = aSleepTime;
+ lock = aLock;
+ lockTest = aLockTest;
+ sleepTime = aSleepTime;
}
public void run() {
- _lock.acquireRead();
- _lockTest.incrementReaderCount();
+ lock.acquireRead();
+ lockTest.incrementReaderCount();
try {
- Thread.sleep(_sleepTime);
+ Thread.sleep(sleepTime);
} catch (InterruptedException e) {
- Assert.fail("ReadLocker thread was interrupted."
- + Thread.currentThread());
+ throw new RuntimeException("ReadLocker thread was interrupted." +
+ Thread.currentThread());
}
- _lock.releaseRead();
- _lockTest.decrementReaderCount();
+ lock.releaseRead();
+ lockTest.decrementReaderCount();
}
}
-
/**
- * WriteLocker acquires a write lock and performs a callback when the lock as
+ * WriteLocker acquires a write lock and performs a callback when the lock as
* been acquired, sleeps for a designated amount of time, releases the write
* lock, and performs a callback after the lock has been released.
*/
class WriteLocker implements Runnable {
- private ReadWriteLock _lock;
- private ReadWriteLockTest _lockTest;
- private int _sleepTime;
+ private ReadWriteLock lock;
+ private ReadWriteLockTest lockTest;
+ private int sleepTime;
public WriteLocker(ReadWriteLock aLock, ReadWriteLockTest aLockTest,
int aSleepTime) {
- _lock = aLock;
- _lockTest = aLockTest;
- _sleepTime = aSleepTime;
+ lock = aLock;
+ lockTest = aLockTest;
+ sleepTime = aSleepTime;
}
public void run() {
- _lock.acquireWrite();
- _lockTest.incrementWriterCount();
+ lock.acquireWrite();
+ lockTest.incrementWriterCount();
try {
- Thread.sleep(_sleepTime);
+ Thread.sleep(sleepTime);
} catch (InterruptedException e) {
- Assert.fail("WriteLocker thread was interrupted: "
- + Thread.currentThread());
+ throw new RuntimeException("WriteLocker thread was interrupted: " +
+ Thread.currentThread());
}
- _lock.releaseWrite();
- _lockTest.decrementWriterCount();
+ lock.releaseWrite();
+ lockTest.decrementWriterCount();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
+import junit.framework.TestCase;
+
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
/**
- * Tests the Or Condition.
- *
+ * Tests the Or Condition.
+ *
* @author Erik Brakkee
*/
public class AndConditionTest extends TestCase {
-
- public void checkResult(boolean aFirst, boolean aSecond, boolean aResult) {
- AndCondition<Integer> and = new AndCondition<Integer>(new FixedCondition<Integer>(aFirst),
- new FixedCondition<Integer>(aSecond));
+ public void checkResult(boolean aFirst, boolean aSecond, boolean aResult) {
+ AndCondition<Integer> and = new AndCondition<Integer>(
+ new FixedCondition<Integer>(aFirst), new FixedCondition<Integer>(
+ aSecond));
assertEquals(aResult, and.matches(0));
}
-
- public void checkResult(boolean[] aValues, boolean aResult) {
+
+ public void checkResult(boolean[] aValues, boolean aResult) {
List<Condition<Integer>> conditions = new ArrayList<Condition<Integer>>();
- for (boolean value: aValues) {
- conditions.add(new FixedCondition<Integer>(value));
+
+ for (boolean value : aValues) {
+ conditions.add(new FixedCondition<Integer>(value));
}
+
AndCondition<Integer> and = new AndCondition<Integer>(conditions);
- assertEquals(aResult, and.matches(new Integer(0)));
+ assertEquals(aResult, and.matches(Integer.valueOf(0)));
}
/**
- * Checks all combinations of two conditions.
- *
+ * Checks all combinations of two conditions.
+ *
*/
- public void testTwoConditions() {
+ public void testTwoConditions() {
checkResult(false, false, false);
checkResult(true, false, false);
- checkResult(false, true, false);
+ checkResult(false, true, false);
checkResult(true, true, true);
}
-
- public void testMultipleConditions() {
- checkResult(new boolean[]{ false, false, false} , false);
- checkResult(new boolean[]{ true, false, false }, false);
- checkResult(new boolean[]{ false, true, false }, false);
- checkResult(new boolean[]{ false, false, true }, false);
- checkResult(new boolean[]{ true, true, true }, true);
+
+ public void testMultipleConditions() {
+ checkResult(new boolean[] { false, false, false }, false);
+ checkResult(new boolean[] { true, false, false }, false);
+ checkResult(new boolean[] { false, true, false }, false);
+ checkResult(new boolean[] { false, false, true }, false);
+ checkResult(new boolean[] { true, true, true }, true);
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
/**
- * Test condition object.
- *
+ * Test condition object.
+ *
* @author Erik Brakkee
*/
public class GreaterThanCondition implements Condition<Integer> {
-
- private int _value;
-
- public GreaterThanCondition(int aValue) {
- _value = aValue;
+ private int value;
+
+ public GreaterThanCondition(int aValue) {
+ value = aValue;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.conditions.Condition#matches(T)
*/
public boolean matches(Integer aObject) {
- return aObject > _value;
+ return aObject > value;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
/**
- * Test condition object.
- *
+ * Test condition object.
+ *
* @author Erik Brakkee
*/
public class LessThanCondition implements Condition<Integer> {
-
- private int _value;
-
- public LessThanCondition(int aValue) {
- _value = aValue;
+ private int value;
+
+ public LessThanCondition(int aValue) {
+ value = aValue;
}
-
- /* (non-Javadoc)
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.conditions.Condition#matches(T)
*/
public boolean matches(Integer aObject) {
- return aObject < _value;
+ return aObject < value;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
+import junit.framework.TestCase;
+
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
/**
- * Tests the Or Condition.
- *
+ * Tests the Or Condition.
+ *
* @author Erik Brakkee
*/
public class OrConditionTest extends TestCase {
-
- public void checkResult(boolean aFirst, boolean aSecond, boolean aResult) {
- OrCondition<Integer> or = new OrCondition<Integer>(new FixedCondition<Integer>(aFirst),
- new FixedCondition<Integer>(aSecond));
+ public void checkResult(boolean aFirst, boolean aSecond, boolean aResult) {
+ OrCondition<Integer> or = new OrCondition<Integer>(
+ new FixedCondition<Integer>(aFirst), new FixedCondition<Integer>(
+ aSecond));
assertEquals(aResult, or.matches(0));
}
-
- public void checkResult(boolean[] aValues, boolean aResult) {
+
+ public void checkResult(boolean[] aValues, boolean aResult) {
List<Condition<Integer>> conditions = new ArrayList<Condition<Integer>>();
- for (boolean value: aValues) {
- conditions.add(new FixedCondition<Integer>(value));
+
+ for (boolean value : aValues) {
+ conditions.add(new FixedCondition<Integer>(value));
}
+
OrCondition<Integer> or = new OrCondition<Integer>(conditions);
- assertEquals(aResult, or.matches(new Integer(0)));
+ assertEquals(aResult, or.matches(Integer.valueOf(0)));
}
/**
- * Checks all combinations of two conditions.
- *
+ * Checks all combinations of two conditions.
+ *
*/
- public void testTwoConditions() {
+ public void testTwoConditions() {
checkResult(false, false, false);
checkResult(true, false, true);
- checkResult(false, true, true);
+ checkResult(false, true, true);
checkResult(true, true, true);
}
-
- public void testMultipleConditions() {
- checkResult(new boolean[]{ false, false, false} , false);
- checkResult(new boolean[]{ true, false, false }, true);
- checkResult(new boolean[]{ false, true, false }, true);
- checkResult(new boolean[]{ false, false, true }, true);
- checkResult(new boolean[]{ true, true, true }, true);
+
+ public void testMultipleConditions() {
+ checkResult(new boolean[] { false, false, false }, false);
+ checkResult(new boolean[] { true, false, false }, true);
+ checkResult(new boolean[] { false, true, false }, true);
+ checkResult(new boolean[] { false, false, true }, true);
+ checkResult(new boolean[] { true, true, true }, true);
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
import junit.framework.TestCase;
/**
- * Tests {@link org.wamblee.conditions.PropertyRegexCondition}.
- *
+ * Tests {@link org.wamblee.conditions.PropertyRegexCondition}.
+ *
* @author Erik Brakkee
*/
public class PropertyRegexConditionTest extends TestCase {
-
- private boolean match(String aProperty, String aRegex, boolean aToLower, TestBean aBean) {
- PropertyRegexCondition<TestBean> condition = new PropertyRegexCondition<TestBean>(aProperty, aRegex, aToLower );
+ private boolean match(String aProperty, String aRegex, boolean aToLower,
+ TestBean aBean) {
+ PropertyRegexCondition<TestBean> condition = new PropertyRegexCondition<TestBean>(
+ aProperty, aRegex, aToLower);
+
return condition.matches(aBean);
}
-
- private void checkMatch(String aProperty, String aRegex, boolean aToLower, TestBean aBean, boolean aResult) {
- assertEquals( aResult, match(aProperty, aRegex, aToLower, aBean));
+
+ private void checkMatch(String aProperty, String aRegex, boolean aToLower,
+ TestBean aBean, boolean aResult) {
+ assertEquals(aResult, match(aProperty, aRegex, aToLower, aBean));
}
-
+
/**
- * Verifies correct matching behavior for several cases.
- *
+ * Verifies correct matching behavior for several cases.
+ *
*/
public void testMatchProperty() {
- TestBean bean = new TestBean("Hallo");
- checkMatch("value", "Hallo", false, bean, true);
+ TestBean bean = new TestBean("Hallo");
+ checkMatch("value", "Hallo", false, bean, true);
checkMatch("value", "all", false, bean, false);
checkMatch("value", ".a.*o", false, bean, true);
- checkMatch("value", "hallo", false, bean, false); // no match when not converting to lower case.
+ checkMatch("value", "hallo", false, bean, false); // no match when not
+ // converting to lower
+ // case.
checkMatch("value", "hallo", true, bean, true); // match!
}
-
+
/**
- * Uses property regex condition for non-existing property.
- * Verifies that a runtime exception is thrown.
- *
+ * Uses property regex condition for non-existing property. Verifies that a
+ * runtime exception is thrown.
+ *
*/
- public void testWrongProperty() {
+ public void testWrongProperty() {
TestBean bean = new TestBean("Hallo");
- try {
- match("bla", ".*", false, bean);
- } catch (RuntimeException e) {
- return; // ok
+
+ try {
+ match("bla", ".*", false, bean);
+ } catch (RuntimeException e) {
+ return; // ok
}
+
fail();
}
-
+
/**
- * Applies condition to a private property. Verifies that a runtime
- * exception is thrown.
- *
+ * Applies condition to a private property. Verifies that a runtime
+ * exception is thrown.
+ *
*/
- public void testPrivateProperty() {
+ public void testPrivateProperty() {
TestBean bean = new TestBean("Hallo");
- try {
- match("privateValue", ".*", false, bean);
- } catch (RuntimeException e) {
- return; // ok
+
+ try {
+ match("privateValue", ".*", false, bean);
+ } catch (RuntimeException e) {
+ return; // ok
}
+
fail();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.conditions;
/**
*
- *
+ *
* @author Erik Brakkee
*/
public class TestBean {
+ private String value;
- private String _value;
-
- public TestBean(String aValue) {
- _value = aValue;
+ public TestBean(String aValue) {
+ value = aValue;
}
-
- public String getValue() {
- return _value;
+
+ public String getValue() {
+ return value;
}
-
- private String getPrivateValue() {
- return _value;
+
+ private String getPrivateValue() {
+ return value;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.general;
import junit.framework.TestCase;
* Tests the bean kernel. The lookup of the bean factory itself can be tested
* only partially. Using a global property file for all test cases would tie all
* test cases together therefore no global property file is used.
- *
+ *
* @author Erik Brakkee
*/
public class BeanKernelTest extends TestCase {
-
/**
* Loads the bean factory based on a property file configuration. Verifies
* the correct bean factory is loaded.
*/
public void testLoadBeanFactoryFromProperties() {
BeanFactory factory = BeanKernel
- .lookupBeanFactory("org/wamblee/general/beankernel.properties");
+ .lookupBeanFactory("org/wamblee/general/beankernel.properties");
assertTrue(factory instanceof TestBeanFactory);
}
/**
- * Loads the bean factory based on a non-existing property file.
- * Verifies that BeanFactoryException is thrown.
+ * Loads the bean factory based on a non-existing property file. Verifies
+ * that BeanFactoryException is thrown.
*
*/
public void testNonExistentPropertyFile() {
try {
BeanKernel
- .lookupBeanFactory("org/wamblee/general/beankernel-nonexistent.properties");
+ .lookupBeanFactory("org/wamblee/general/beankernel-nonexistent.properties");
} catch (BeanFactoryException e) {
return; // ok
}
+
fail();
}
-
+
/**
- * Loads the bean factory based on a property file with a non-existing
- * bean factory defined in it.
- * Verifies that BeanFactoryException is thrown.
+ * Loads the bean factory based on a property file with a non-existing bean
+ * factory defined in it. Verifies that BeanFactoryException is thrown.
*
*/
public void testNonExistentBeanFactory() {
try {
BeanKernel
- .lookupBeanFactory("org/wamblee/general/beankernel-wrong.properties");
+ .lookupBeanFactory("org/wamblee/general/beankernel-wrong.properties");
} catch (BeanFactoryException e) {
return; // ok
}
+
fail();
}
-
/**
* Retrieves a bean factory throug the bean kernel. Verifies that beans can
*/
public void testRetrieveFactory() {
BeanKernel.overrideBeanFactory(new TestBeanFactory()); // bypass
- // default
- // property
- // lookup
+ // default
+ // property
+ // lookup
+
BeanFactory factory = BeanKernel.getBeanFactory();
assertNotNull(factory);
assertEquals("hello", factory.find(String.class));
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.general;
import junit.framework.TestCase;
/**
- * Tests the pair class.
+ * Tests the pair class.
*/
public class PairTest extends TestCase {
-
- public void testPair() {
- Pair<Integer, String> pair = new Pair<Integer, String>(10, "hello");
- assertEquals(new Integer(10), pair.getFirst());
+ public void testPair() {
+ Pair<Integer, String> pair = new Pair<Integer, String>(10, "hello");
+ assertEquals(Integer.valueOf(10), pair.getFirst());
assertEquals("hello", pair.getSecond());
-
+
Pair<Integer, String> pair2 = new Pair<Integer, String>(pair);
- assertEquals(new Integer(10), pair2.getFirst());
+ assertEquals(Integer.valueOf(10), pair2.getFirst());
assertEquals("hello", pair2.getSecond());
-
-
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.general;
public class TestBeanFactory implements BeanFactory {
+ @Override
+ public Object find(String aId) {
+ return null;
+ }
- @Override
- public Object find(String aId) {
- return null;
- }
+ @Override
+ public <T> T find(Class<T> aClass) {
+ if (aClass.equals(String.class)) {
+ return (T) "hello";
+ }
- @Override
- public <T> T find(Class<T> aClass) {
- if ( aClass.equals(String.class)) {
- return (T)"hello";
- }
- return null;
- }
-
- @Override
- public <T> T find(String aId, Class<T> aClass) {
- return null;
- }
+ return null;
+ }
+ @Override
+ public <T> T find(String aId, Class<T> aClass) {
+ return null;
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
+import junit.framework.TestCase;
+
import java.io.IOException;
import java.io.InputStream;
-
-import junit.framework.TestCase;
-
/**
* Tests for the classpath resource.
*/
public class ClassPathResourceTest extends TestCase {
-
/**
* Loads an existing resource from the class path. Verifies it is found.
*
*/
public void testResourceFound() throws IOException {
ClassPathResource resource = new ClassPathResource(
- "org/wamblee/io/myresource.txt");
+ "org/wamblee/io/myresource.txt");
InputStream is = resource.getInputStream();
String data = FileSystemUtils.read(is);
assertEquals("This is my resource", data);
public void testResourceNotFound() {
try {
ClassPathResource resource = new ClassPathResource(
- "org/wamblee/io/myresource-nonexistent.txt");
- InputStream is = resource.getInputStream();
+ "org/wamblee/io/myresource-nonexistent.txt");
+ resource.getInputStream();
} catch (IOException e) {
return; // ok
}
+
fail();
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
-import static org.mockito.Mockito.*;
import junit.framework.TestCase;
import org.apache.oro.io.AwkFilenameFilter;
+import static org.mockito.Mockito.*;
public class DirectoryMonitorTest extends TestCase {
-
- private static final String REGEX = "^.*\\.txt$";
- private static final String FILE1 = "file1.txt";
-
- private TestData _data;
- private DirectoryMonitor.Listener _listener;
-
- private DirectoryMonitor _monitor;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- _data = new TestData(this);
- _data.clean();
- _listener = mock(DirectoryMonitor.Listener.class);
- _monitor = new DirectoryMonitor(_data.getRoot(), new AwkFilenameFilter(
- REGEX), _listener);
- }
-
- public void testEmptyDir() {
- // Nothing is expected to be called.
- for (int i = 0; i < 10; i++) {
- _monitor.poll();
- verifyNoMoreInteractions(_listener);
- }
- }
-
- public void testFileCreated() {
- _data.createFile(FILE1, "hello");
- _monitor.poll();
- verify(_listener).fileCreated(_data.getFile(FILE1));
- }
-
- public void testFileDeleted() {
- _data.createFile(FILE1, "hello");
- _monitor.poll();
- reset(_listener);
-
- _data.deleteFile(FILE1);
- _monitor.poll();
-
- verify(_listener).fileDeleted(_data.getFile(FILE1));
- verifyNoMoreInteractions(_listener);
- }
-
- public void testFileChanged() throws InterruptedException {
- _data.createFile(FILE1, "hello");
- _monitor.poll();
- reset(_listener);
-
- Thread.sleep(2000);
- _data.deleteFile(FILE1);
- _data.createFile(FILE1, "bla");
-
- _monitor.poll();
- verify(_listener).fileChanged(_data.getFile(FILE1));
- verifyNoMoreInteractions(_listener);
- }
-
- public void testFileFilterIsUsed() {
- _monitor.poll();
-
- _data.createFile("file.xml", "hello");
- _monitor.poll();
- verifyNoMoreInteractions(_listener);
- }
-
- public void testDirectoryIsIgnored() {
- _monitor.poll();
- _data.createDir(FILE1);
- _monitor.poll();
- verifyNoMoreInteractions(_listener);
- }
-
- public void testExceptionsWIllLeadToRepeatedNotifications() {
- _monitor.poll();
- _data.createFile(FILE1, "hello");
-
- stubVoid(_listener).toThrow(new RuntimeException()).on().
- fileCreated(_data.getFile(FILE1));
-
- try {
- _monitor.poll();
- } catch (RuntimeException e) {
- reset(_listener);
-
- // polling again should lead to the same filecreated call.
- // this time no exception is thrown.
-
- _monitor.poll();
- verify(_listener).fileCreated(_data.getFile(FILE1));
- verifyNoMoreInteractions(_listener);
- return;
- }
- fail(); // should not get here.
-
-
- }
+ private static final String REGEX = "^.*\\.txt$";
+ private static final String FILE1 = "file1.txt";
+ private TestData data;
+ private DirectoryMonitor.Listener listener;
+ private DirectoryMonitor monitor;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ data = new TestData(this);
+ data.clean();
+ listener = mock(DirectoryMonitor.Listener.class);
+ monitor = new DirectoryMonitor(data.getRoot(), new AwkFilenameFilter(
+ REGEX), listener);
+ }
+
+ public void testEmptyDir() {
+ // Nothing is expected to be called.
+ for (int i = 0; i < 10; i++) {
+ monitor.poll();
+ verifyNoMoreInteractions(listener);
+ }
+ }
+
+ public void testFileCreated() {
+ data.createFile(FILE1, "hello");
+ monitor.poll();
+ verify(listener).fileCreated(data.getFile(FILE1));
+ }
+
+ public void testFileDeleted() {
+ data.createFile(FILE1, "hello");
+ monitor.poll();
+ reset(listener);
+
+ data.deleteFile(FILE1);
+ monitor.poll();
+
+ verify(listener).fileDeleted(data.getFile(FILE1));
+ verifyNoMoreInteractions(listener);
+ }
+
+ public void testFileChanged() throws InterruptedException {
+ data.createFile(FILE1, "hello");
+ monitor.poll();
+ reset(listener);
+
+ Thread.sleep(2000);
+ data.deleteFile(FILE1);
+ data.createFile(FILE1, "bla");
+
+ monitor.poll();
+ verify(listener).fileChanged(data.getFile(FILE1));
+ verifyNoMoreInteractions(listener);
+ }
+
+ public void testFileFilterIsUsed() {
+ monitor.poll();
+
+ data.createFile("file.xml", "hello");
+ monitor.poll();
+ verifyNoMoreInteractions(listener);
+ }
+
+ public void testDirectoryIsIgnored() {
+ monitor.poll();
+ data.createDir(FILE1);
+ monitor.poll();
+ verifyNoMoreInteractions(listener);
+ }
+
+ public void testExceptionsWIllLeadToRepeatedNotifications() {
+ monitor.poll();
+ data.createFile(FILE1, "hello");
+
+ stubVoid(listener).toThrow(new RuntimeException()).on().fileCreated(
+ data.getFile(FILE1));
+
+ try {
+ monitor.poll();
+ } catch (RuntimeException e) {
+ reset(listener);
+
+ // polling again should lead to the same filecreated call.
+ // this time no exception is thrown.
+ monitor.poll();
+ verify(listener).fileCreated(data.getFile(FILE1));
+ verifyNoMoreInteractions(listener);
+
+ return;
+ }
+
+ fail(); // should not get here.
+ }
}
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.io;
-import java.io.File;
-
import org.apache.oro.io.AwkFilenameFilter;
+import java.io.File;
+
/**
*
- *
+ *
* @author Erik Brakkee
*/
public class DirectoryMonitorTestProgram {
-
- public static void main(String[] aArgs) throws Exception {
-
- DirectoryMonitor monitor = new DirectoryMonitor(new File("."),
- new AwkFilenameFilter(".*\\.txt"), new DirectoryMonitor.Listener() {
- public void fileChanged(File aFile) {
- System.out.println("changed " + aFile);
- }
- public void fileCreated(File aFile) {
- System.out.println("created " + aFile);
- }
- public void fileDeleted(File aFile) {
- System.out.println("deleted " + aFile);
- }
- });
-
- for (;;) {
+ public static void main(String[] aArgs) throws Exception {
+ DirectoryMonitor monitor = new DirectoryMonitor(new File("."),
+ new AwkFilenameFilter(".*\\.txt"), new DirectoryMonitor.Listener() {
+ public void fileChanged(File aFile) {
+ System.out.println("changed " + aFile);
+ }
+
+ public void fileCreated(File aFile) {
+ System.out.println("created " + aFile);
+ }
+
+ public void fileDeleted(File aFile) {
+ System.out.println("deleted " + aFile);
+ }
+ });
+
+ for (;;) {
monitor.poll();
Thread.sleep(1000);
}
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.io;
+import junit.framework.TestCase;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-
-import junit.framework.TestCase;
-
/**
- * Tests the file resource.
- *
+ * Tests the file resource.
+ *
* @author Erik Brakkee
*/
public class FileResourceTest extends TestCase {
-
/**
* Loads an existing resource. Verifies it is found.
*
*/
public void testResourceFound() throws IOException {
- FileResource resource = new FileResource( new File(
- FileSystemUtils.getTestInputDir(FileResourceTest.class),
- "myresource.txt"));
+ FileResource resource = new FileResource(new File(FileSystemUtils
+ .getTestInputDir(FileResourceTest.class), "myresource.txt"));
InputStream is = resource.getInputStream();
String data = FileSystemUtils.read(is);
assertEquals("This is my resource", data);
}
/**
- * Loads a non-existing resource. Verifies that an IO
- * exception is thrown.
+ * Loads a non-existing resource. Verifies that an IO exception is thrown.
*
*/
public void testResourceNotFound() {
try {
- FileResource resource = new FileResource( new File(
- FileSystemUtils.getTestInputDir(FileResourceTest.class),
- "myresource-nonexistent.txt"));
- InputStream is = resource.getInputStream();
+ FileResource resource = new FileResource(new File(FileSystemUtils
+ .getTestInputDir(FileResourceTest.class),
+ "myresource-nonexistent.txt"));
+ resource.getInputStream();
} catch (IOException e) {
return; // ok
}
+
fail();
}
}
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+
import java.net.URL;
import java.net.URLDecoder;
+
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
-import java.security.CodeSource;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import java.security.CodeSource;
/**
* File system utilities.
* @author Erik Brakkee
*/
public final class FileSystemUtils {
-
- private static final Log LOG = LogFactory.getLog(FileSystemUtils.class);
-
- /**
- * Test output directory relative to the sub project.
- */
- private static final String TEST_OUTPUT_DIR = "../target/testoutput";
-
- /**
- * Test input directory relative to the sub project.
- */
- private static final String TEST_INPUT_DIR = "../src/test/resources";
-
- /*
- * Disabled.
- *
- */
- private FileSystemUtils() {
- // Empty
- }
-
- /**
- * Deletes a directory recursively. The test case will fail if the directory
- * does not exist or if deletion fails.
- *
- * @param aDir
- * Directory to delete.
- */
- public static void deleteDirRecursively(String aDir) {
- deleteDirRecursively(new File(aDir));
- }
-
- /**
- * Deletes a directory recursively. See {@link #deleteDirRecursively}.
- *
- * @param aDir
- * Directory.
- */
- public static void deleteDirRecursively(File aDir) {
- TestCase.assertTrue(aDir.isDirectory());
-
- for (File file : aDir.listFiles()) {
- if (file.isDirectory()) {
- deleteDirRecursively(file);
- } else {
- delete(file);
- }
- }
-
- delete(aDir);
- }
-
- /**
- * Deletes a file or directory. The test case will fail if the file or
- * directory does not exist or if deletion fails. Deletion of a non-empty
- * directory will always fail.
- *
- * @param aFile
- * File or directory to delete.
- */
- public static void delete(File aFile) {
- TestCase.assertTrue(aFile.delete());
- }
-
- /**
- * Gets a path relative to a sub project. This utility should be used to
- * easily access file paths within a subproject without requiring any
- * specific Eclipse configuration.
- *
- * @param aRelativePath
- * Relative path.
- * @param aTestClass
- * Test class.
- */
- public static File getPath(String aRelativePath, Class aTestClass) {
- CodeSource source = aTestClass.getProtectionDomain().getCodeSource();
- if (source == null) {
- LOG.warn("Could not obtain path for '" + aRelativePath
- + "' for class " + aTestClass
- + ", using relative path as is");
- return new File(aRelativePath);
- }
- URL location = source.getLocation();
- String protocol = location.getProtocol();
- if (!protocol.equals("file")) {
- LOG.warn("protocol is not 'file': " + location);
- return new File(aRelativePath);
- }
-
- String path = location.getPath();
- try {
- path = URLDecoder.decode(location.getPath(), "UTF-8");
- } catch (UnsupportedEncodingException e) {
- // ignore it.. just don't decode
- LOG.warn("Decoding path failed: '" + location.getPath() + "'", e);
- }
-
- return new File(new File(path).getParentFile(), aRelativePath);
- }
-
- /**
- * Ensures that a directory hierarchy exists (recursively if needed). If it
- * is not possible to create the directory, then the test case will fail.
- *
- * @param aDir
- * Directory to create.
- */
- public static void createDir(File aDir) {
- if (aDir.exists() && !aDir.isDirectory()) {
- TestCase.fail("'" + aDir
- + "' already exists and is not a directory");
- }
- if (aDir.exists()) {
- return;
- }
- createDir(aDir.getParentFile());
- TestCase.assertTrue("Could not create '" + aDir + "'", aDir.mkdir());
- }
-
- /**
- * Creates a file in a directory.
- * @param aDir Directory path. Will be created if it does not exist.
- * @param aName Filename.
- * @param aContents Contents.
- */
- public static void createFile(File aDir, String aName, InputStream aContents) {
- createDir(aDir);
- try {
- OutputStream os = new FileOutputStream(new File(aDir, aName));
- copyStream(aContents, os);
- } catch (IOException e) {
- e.printStackTrace();
- TestCase.fail(e.getMessage());
- }
- }
-
- /**
- * Gets the test output directory for a specific test class.
- *
- * @param aTestClass
- * Test class.
- * @return Test output directory.
- */
- public static File getTestOutputDir(Class aTestClass) {
- File file = getPath(TEST_OUTPUT_DIR, aTestClass);
- String className = aTestClass.getName();
- String classRelPath = className.replaceAll("\\.", "/");
- return new File(file, classRelPath);
- }
-
- /**
- * Gets the test input directory for a specific test class.
- *
- * @param aTestClass
- * Test class.
- * @return Test input directory.
- */
- public static File getTestInputDir(Class aTestClass) {
- File file = getPath(TEST_INPUT_DIR, aTestClass);
- String packageName = aTestClass.getPackage().getName();
- String packagePath = packageName.replaceAll("\\.", "/");
- return new File(file, packagePath);
- }
-
- /**
- * Creates a directory hierarchy for the output directory of a test class if
- * needed.
- *
- * @param aTestClass
- * Test class
- * @return Test directory.
- */
- public static File createTestOutputDir(Class aTestClass) {
- File file = getTestOutputDir(aTestClass);
- createDir(file);
- return file;
- }
-
- /**
- * Gets a test output file name. This returns a File object representing the
- * output file and ensures that the directory where the file will be created
- * already exists.
- *
- * @param aName
- * Name of the file.
- * @param aTestClass
- * Test class.
- * @return File.
- */
- public static File getTestOutputFile(String aName, Class aTestClass) {
- File file = new File(getTestOutputDir(aTestClass), aName);
- createDir(file.getParentFile());
- return file;
- }
-
- public static String read(InputStream aIs) throws IOException {
- try {
- StringBuffer buffer = new StringBuffer();
- int c;
- while ((c = aIs.read()) != -1) {
- buffer.append((char) c);
- }
- return buffer.toString();
- } finally {
- aIs.close();
- }
- }
-
- /**
- * Copies an input stream to an output stream.
- *
- * @param aIs
- * Input stream.
- * @param aOs
- * Output stream.
- */
- public static void copyStream(InputStream aIs, OutputStream aOs) {
- try {
- int c;
- while ((c = aIs.read()) != -1) {
- aOs.write(c);
- }
- aIs.close();
- aOs.close();
- } catch (IOException e) {
- e.printStackTrace();
- Assert.fail(e.getMessage());
- }
- }
-
- /**
- * Recursively copy a directory.
- *
- * @param aSrc
- * Source directory
- * @param aTarget
- * Target directory.
- */
- public static void copyDir(File aSrc, File aTarget) {
- Assert.assertTrue(aSrc.isDirectory());
- Assert.assertTrue(!aTarget.exists());
-
- aTarget.mkdirs();
-
- File[] files = aSrc.listFiles();
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- if (file.isDirectory()) {
- if (!file.getName().equals(".svn")) {
- copyDir(new File(aSrc, file.getName()), new File(aTarget,
- file.getName()));
- }
- } else {
- copyFile(file, new File(aTarget, file.getName()));
- }
- }
- }
-
- /**
- * Copy a file. If copying fails then the testcase will fail.
- *
- * @param aSrc
- * Source file.
- * @param aTarget
- * Target file.
- */
- public static void copyFile(File aSrc, File aTarget) {
-
- try {
- FileInputStream fis = new FileInputStream(aSrc);
- FileOutputStream fos = new FileOutputStream(aTarget);
- FileChannel fcin = fis.getChannel();
- FileChannel fcout = fos.getChannel();
-
- // map input file
-
- MappedByteBuffer mbb = fcin.map(FileChannel.MapMode.READ_ONLY, 0,
- fcin.size());
-
- // do the file copy
- fcout.write(mbb);
-
- // finish up
-
- fcin.close();
- fcout.close();
- fis.close();
- fos.close();
- } catch (IOException e) {
- Assert.assertTrue("Copying file " + aSrc.getPath() + " to "
- + aTarget.getPath() + " failed.", false);
- }
- }
-
- /**
- * Remove all files within a given directory including the directory itself.
- * This only attempts to remove regular files and not directories within the
- * directory. If the directory contains a nested directory, the deletion
- * will fail. The test case will fail if this fails.
- *
- * @param aDir
- * Directory to remove.
- */
- public static void deleteDir(File aDir) {
- cleanDir(aDir);
- delete(aDir);
- }
-
- /**
- * Remove all regular files within a given directory.
- *
- * @param outputDirName
- */
- public static void cleanDir(File aDir) {
- if (!aDir.exists()) {
- return; // nothing to do.
- }
- File[] entries = aDir.listFiles();
- for (int i = 0; i < entries.length; i++) {
- File file = entries[i];
- if (file.isFile()) {
- Assert.assertTrue("Could not delete " + entries[i].getPath(),
- entries[i].delete());
- }
- }
- }
+ private static final Log LOG = LogFactory.getLog(FileSystemUtils.class);
+
+ /**
+ * Test output directory relative to the sub project.
+ */
+ private static final String TEST_OUTPUT_DIR = "../target/testoutput";
+
+ /**
+ * Test input directory relative to the sub project.
+ */
+ private static final String TEST_INPUT_DIR = "../src/test/resources";
+
+ /*
+ * Disabled.
+ */
+ private FileSystemUtils() {
+ // Empty
+ }
+
+ /**
+ * Deletes a directory recursively. The test case will fail if the directory
+ * does not exist or if deletion fails.
+ *
+ * @param aDir
+ * Directory to delete.
+ */
+ public static void deleteDirRecursively(String aDir) {
+ deleteDirRecursively(new File(aDir));
+ }
+
+ /**
+ * Deletes a directory recursively. See {@link #deleteDirRecursively}.
+ *
+ * @param aDir
+ * Directory.
+ */
+ public static void deleteDirRecursively(File aDir) {
+ TestCase.assertTrue(aDir.isDirectory());
+
+ for (File file : aDir.listFiles()) {
+ if (file.isDirectory()) {
+ deleteDirRecursively(file);
+ } else {
+ delete(file);
+ }
+ }
+
+ delete(aDir);
+ }
+
+ /**
+ * Deletes a file or directory. The test case will fail if the file or
+ * directory does not exist or if deletion fails. Deletion of a non-empty
+ * directory will always fail.
+ *
+ * @param aFile
+ * File or directory to delete.
+ */
+ public static void delete(File aFile) {
+ TestCase.assertTrue(aFile.delete());
+ }
+
+ /**
+ * Gets a path relative to a sub project. This utility should be used to
+ * easily access file paths within a subproject without requiring any
+ * specific Eclipse configuration.
+ *
+ * @param aRelativePath
+ * Relative path.
+ * @param aTestClass
+ * Test class.
+ */
+ public static File getPath(String aRelativePath, Class aTestClass) {
+ CodeSource source = aTestClass.getProtectionDomain().getCodeSource();
+
+ if (source == null) {
+ LOG.warn("Could not obtain path for '" + aRelativePath +
+ "' for class " + aTestClass + ", using relative path as is");
+
+ return new File(aRelativePath);
+ }
+
+ URL location = source.getLocation();
+ String protocol = location.getProtocol();
+
+ if (!protocol.equals("file")) {
+ LOG.warn("protocol is not 'file': " + location);
+
+ return new File(aRelativePath);
+ }
+
+ String path = location.getPath();
+
+ try {
+ path = URLDecoder.decode(location.getPath(), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // ignore it.. just don't decode
+ LOG.warn("Decoding path failed: '" + location.getPath() + "'", e);
+ }
+
+ return new File(new File(path).getParentFile(), aRelativePath);
+ }
+
+ /**
+ * Ensures that a directory hierarchy exists (recursively if needed). If it
+ * is not possible to create the directory, then the test case will fail.
+ *
+ * @param aDir
+ * Directory to create.
+ */
+ public static void createDir(File aDir) {
+ if (aDir.exists() && !aDir.isDirectory()) {
+ TestCase.fail("'" + aDir +
+ "' already exists and is not a directory");
+ }
+
+ if (aDir.exists()) {
+ return;
+ }
+
+ createDir(aDir.getParentFile());
+ TestCase.assertTrue("Could not create '" + aDir + "'", aDir.mkdir());
+ }
+
+ /**
+ * Creates a file in a directory.
+ *
+ * @param aDir
+ * Directory path. Will be created if it does not exist.
+ * @param aName
+ * Filename.
+ * @param aContents
+ * Contents.
+ */
+ public static void createFile(File aDir, String aName, InputStream aContents) {
+ createDir(aDir);
+
+ try {
+ OutputStream os = new FileOutputStream(new File(aDir, aName));
+ copyStream(aContents, os);
+ } catch (IOException e) {
+ e.printStackTrace();
+ TestCase.fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Gets the test output directory for a specific test class.
+ *
+ * @param aTestClass
+ * Test class.
+ * @return Test output directory.
+ */
+ public static File getTestOutputDir(Class aTestClass) {
+ File file = getPath(TEST_OUTPUT_DIR, aTestClass);
+ String className = aTestClass.getName();
+ String classRelPath = className.replaceAll("\\.", "/");
+
+ return new File(file, classRelPath);
+ }
+
+ /**
+ * Gets the test input directory for a specific test class.
+ *
+ * @param aTestClass
+ * Test class.
+ * @return Test input directory.
+ */
+ public static File getTestInputDir(Class aTestClass) {
+ File file = getPath(TEST_INPUT_DIR, aTestClass);
+ String packageName = aTestClass.getPackage().getName();
+ String packagePath = packageName.replaceAll("\\.", "/");
+
+ return new File(file, packagePath);
+ }
+
+ /**
+ * Creates a directory hierarchy for the output directory of a test class if
+ * needed.
+ *
+ * @param aTestClass
+ * Test class
+ * @return Test directory.
+ */
+ public static File createTestOutputDir(Class aTestClass) {
+ File file = getTestOutputDir(aTestClass);
+ createDir(file);
+
+ return file;
+ }
+
+ /**
+ * Gets a test output file name. This returns a File object representing the
+ * output file and ensures that the directory where the file will be created
+ * already exists.
+ *
+ * @param aName
+ * Name of the file.
+ * @param aTestClass
+ * Test class.
+ * @return File.
+ */
+ public static File getTestOutputFile(String aName, Class aTestClass) {
+ File file = new File(getTestOutputDir(aTestClass), aName);
+ createDir(file.getParentFile());
+
+ return file;
+ }
+
+ public static String read(InputStream aIs) throws IOException {
+ try {
+ StringBuffer buffer = new StringBuffer();
+ int c;
+
+ while ((c = aIs.read()) != -1) {
+ buffer.append((char) c);
+ }
+
+ return buffer.toString();
+ } finally {
+ aIs.close();
+ }
+ }
+
+ /**
+ * Copies an input stream to an output stream.
+ *
+ * @param aIs
+ * Input stream.
+ * @param aOs
+ * Output stream.
+ */
+ public static void copyStream(InputStream aIs, OutputStream aOs) {
+ try {
+ int c;
+
+ while ((c = aIs.read()) != -1) {
+ aOs.write(c);
+ }
+
+ aIs.close();
+ aOs.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Recursively copy a directory.
+ *
+ * @param aSrc
+ * Source directory
+ * @param aTarget
+ * Target directory.
+ */
+ public static void copyDir(File aSrc, File aTarget) {
+ Assert.assertTrue(aSrc.isDirectory());
+ Assert.assertTrue(!aTarget.exists());
+
+ if (!aTarget.mkdirs()) {
+ Assert.fail("Could not create target directory '" + aTarget + "'");
+ }
+
+ File[] files = aSrc.listFiles();
+
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+
+ if (file.isDirectory()) {
+ if (!file.getName().equals(".svn")) {
+ copyDir(new File(aSrc, file.getName()), new File(aTarget,
+ file.getName()));
+ }
+ } else {
+ copyFile(file, new File(aTarget, file.getName()));
+ }
+ }
+ }
+
+ /**
+ * Copy a file. If copying fails then the testcase will fail.
+ *
+ * @param aSrc
+ * Source file.
+ * @param aTarget
+ * Target file.
+ */
+ public static void copyFile(File aSrc, File aTarget) {
+ try {
+ FileInputStream fis = new FileInputStream(aSrc);
+ FileOutputStream fos = new FileOutputStream(aTarget);
+ FileChannel fcin = fis.getChannel();
+ FileChannel fcout = fos.getChannel();
+
+ // map input file
+ MappedByteBuffer mbb = fcin.map(FileChannel.MapMode.READ_ONLY, 0,
+ fcin.size());
+
+ // do the file copy
+ fcout.write(mbb);
+
+ // finish up
+ fcin.close();
+ fcout.close();
+ fis.close();
+ fos.close();
+ } catch (IOException e) {
+ Assert.assertTrue("Copying file " + aSrc.getPath() + " to " +
+ aTarget.getPath() + " failed.", false);
+ }
+ }
+
+ /**
+ * Remove all files within a given directory including the directory itself.
+ * This only attempts to remove regular files and not directories within the
+ * directory. If the directory contains a nested directory, the deletion
+ * will fail. The test case will fail if this fails.
+ *
+ * @param aDir
+ * Directory to remove.
+ */
+ public static void deleteDir(File aDir) {
+ cleanDir(aDir);
+ delete(aDir);
+ }
+
+ /**
+ * Remove all regular files within a given directory.
+ *
+ * @param outputDirName
+ */
+ public static void cleanDir(File aDir) {
+ if (!aDir.exists()) {
+ return; // nothing to do.
+ }
+
+ File[] entries = aDir.listFiles();
+
+ for (int i = 0; i < entries.length; i++) {
+ File file = entries[i];
+
+ if (file.isFile()) {
+ Assert.assertTrue("Could not delete " + entries[i].getPath(),
+ entries[i].delete());
+ }
+ }
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.io;
+import junit.framework.TestCase;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-
-import junit.framework.TestCase;
-
/**
- * Tests the stream resource.
- *
+ * Tests the stream resource.
+ *
* @author Erik Brakkee
*/
public class StreamResourceTest extends TestCase {
-
/**
* Loads an existing resource. Verifies it is found.
*
*/
public void testResourceFound() throws IOException {
- File file = new File(
- FileSystemUtils.getTestInputDir(StreamResourceTest.class),
- "myresource.txt");
- assertTrue(file.canRead());
+ File file = new File(FileSystemUtils
+ .getTestInputDir(StreamResourceTest.class), "myresource.txt");
+ assertTrue(file.canRead());
+
InputStream fileIs = new FileInputStream(file);
InputResource resource = new StreamResource(fileIs);
InputStream is = resource.getInputStream();
String data = FileSystemUtils.read(is);
assertEquals("This is my resource", data);
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.io;
import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
import junit.framework.Assert;
* @author Erik Brakkee
*/
public final class TestData {
-
- private Object _testcase;
- private File _root;
-
- /**
- * Test data to be constructed in the setUp of a test. {@link #clean()} must
- * be called to make sure that this directory is empty before executing a
- * test.
- */
- public TestData(Object aTestcase) {
- _testcase = aTestcase;
- _root = getTestRootDir(aTestcase);
- FileSystemUtils.createDir(_root);
- }
-
- /**
- * Obtain root directory of JUnit tests.
- *
- * @return Directory name.
- */
- private static File getTestRootDir(Object aTestcase) {
- return FileSystemUtils.getTestOutputDir(aTestcase.getClass());
- }
-
- public void createFile(String aRelative, String aFile, InputStream aContents) {
- FileSystemUtils
- .createFile(new File(_root, aRelative), aFile, aContents);
- }
-
- public void createFile(String aFile, String aContents) {
- createFile(".", aFile, aContents);
- }
-
- public void createFile(String aRelative, String aFile, String aContents) {
- InputStream is = new ByteArrayInputStream(aContents.getBytes());
- FileSystemUtils.createFile(new File(_root, aRelative), aFile, is);
- }
-
- public void deleteFile(String aFile) {
- deleteFile(".", aFile);
- }
-
- public void deleteFile(String aRelative, String aFile) {
- FileSystemUtils.delete(new File(_root, aFile));
- }
-
- /**
- * Returns a temporary directory.
- *
- * @return Temporary directory.
- */
- public File getTmpDir() {
- return new File(_root, "tmpdir");
- }
-
- /**
- * Cleans up the test output directory.
- */
- public void clean() {
- FileSystemUtils.deleteDirRecursively(_root);
- FileSystemUtils.createDir(_root);
- }
-
- /**
- * Recursively copy a directory contents to the test output directory.
- *
- * @param sSrc
- * Source directory to copy.
- */
- public void copyDir(File aSrc) {
- FileSystemUtils.copyDir(aSrc, _root);
- }
-
- /**
- * Copies a classpath resource to a relative path in the test output
- * directory.
- *
- * @param aResource
- * Resource to copy.
- * @param aRelativePath
- * Relative path.
- */
- public void copyResource(String aResource, String aRelativePath) {
- try {
- InputStream is = new ClassPathResource(aResource).getInputStream();
- FileOutputStream fos = new FileOutputStream(new File(_root,
- aRelativePath));
- FileSystemUtils.copyStream(is, fos);
- } catch (IOException e) {
- e.printStackTrace();
- Assert.fail(e.getMessage());
- }
- }
-
- /**
- * Copies a resource to the root directory of the test output.
- *
- * @param aResource
- * Resource.
- */
- public void copyResource(String aResource) {
- String basename = new File(aResource).getName();
- copyResource(aResource, basename);
- }
-
- public void createDir(String aRelative) {
- FileSystemUtils.createDir(new File(_root, aRelative));
- }
-
- /**
- * Deletes a file or directory relative to the test output root.
- *
- * @param aRelative
- * Relative path. The testcase will fail if the file or directory
- * cannot be removed.
- */
- public void delete(String aRelative) {
- FileSystemUtils.delete(new File(_root, aRelative));
- }
-
- /**
- * Deletes a directory including its contents.
- *
- * @param aRelative
- * Relative path.
- */
- public void deleteDir(String aRelative) {
- FileSystemUtils.deleteDir(new File(_root, aRelative));
- }
-
- /**
- * Deletes a directory recursively.
- *
- * @param aRelative
- * Relative path.
- */
- public void deleteDirRecursively(String aRelative) {
- FileSystemUtils.deleteDir(new File(_root, aRelative));
- }
-
- /**
- * Gets the root of the test output directory.
- *
- * @return Root of the test output.
- */
- public File getRoot() {
- return _root;
- }
-
- /**
- * Gets a file object for a relative path.
- */
- public File getFile(String aRelative) {
- return new File(_root, aRelative);
- }
+ private File root;
+
+ /**
+ * Test data to be constructed in the setUp of a test. {@link #clean()} must
+ * be called to make sure that this directory is empty before executing a
+ * test.
+ */
+ public TestData(Object aTestcase) {
+ root = getTestRootDir(aTestcase);
+ FileSystemUtils.createDir(root);
+ }
+
+ /**
+ * Obtain root directory of JUnit tests.
+ *
+ * @return Directory name.
+ */
+ private static File getTestRootDir(Object aTestcase) {
+ return FileSystemUtils.getTestOutputDir(aTestcase.getClass());
+ }
+
+ public void createFile(String aRelative, String aFile, InputStream aContents) {
+ FileSystemUtils.createFile(new File(root, aRelative), aFile, aContents);
+ }
+
+ public void createFile(String aFile, String aContents) {
+ createFile(".", aFile, aContents);
+ }
+
+ public void createFile(String aRelative, String aFile, String aContents) {
+ InputStream is = new ByteArrayInputStream(aContents.getBytes());
+ FileSystemUtils.createFile(new File(root, aRelative), aFile, is);
+ }
+
+ public void deleteFile(String aFile) {
+ deleteFile(".", aFile);
+ }
+
+ public void deleteFile(String aRelative, String aFile) {
+ FileSystemUtils.delete(new File(root, aFile));
+ }
+
+ /**
+ * Returns a temporary directory.
+ *
+ * @return Temporary directory.
+ */
+ public File getTmpDir() {
+ return new File(root, "tmpdir");
+ }
+
+ /**
+ * Cleans up the test output directory.
+ */
+ public void clean() {
+ FileSystemUtils.deleteDirRecursively(root);
+ FileSystemUtils.createDir(root);
+ }
+
+ /**
+ * Recursively copy a directory contents to the test output directory.
+ *
+ * @param sSrc
+ * Source directory to copy.
+ */
+ public void copyDir(File aSrc) {
+ FileSystemUtils.copyDir(aSrc, root);
+ }
+
+ /**
+ * Copies a classpath resource to a relative path in the test output
+ * directory.
+ *
+ * @param aResource
+ * Resource to copy.
+ * @param aRelativePath
+ * Relative path.
+ */
+ public void copyResource(String aResource, String aRelativePath) {
+ try {
+ InputStream is = new ClassPathResource(aResource).getInputStream();
+ FileOutputStream fos = new FileOutputStream(new File(root,
+ aRelativePath));
+ FileSystemUtils.copyStream(is, fos);
+ } catch (IOException e) {
+ e.printStackTrace();
+ Assert.fail(e.getMessage());
+ }
+ }
+
+ /**
+ * Copies a resource to the root directory of the test output.
+ *
+ * @param aResource
+ * Resource.
+ */
+ public void copyResource(String aResource) {
+ String basename = new File(aResource).getName();
+ copyResource(aResource, basename);
+ }
+
+ public void createDir(String aRelative) {
+ FileSystemUtils.createDir(new File(root, aRelative));
+ }
+
+ /**
+ * Deletes a file or directory relative to the test output root.
+ *
+ * @param aRelative
+ * Relative path. The testcase will fail if the file or directory
+ * cannot be removed.
+ */
+ public void delete(String aRelative) {
+ FileSystemUtils.delete(new File(root, aRelative));
+ }
+
+ /**
+ * Deletes a directory including its contents.
+ *
+ * @param aRelative
+ * Relative path.
+ */
+ public void deleteDir(String aRelative) {
+ FileSystemUtils.deleteDir(new File(root, aRelative));
+ }
+
+ /**
+ * Deletes a directory recursively.
+ *
+ * @param aRelative
+ * Relative path.
+ */
+ public void deleteDirRecursively(String aRelative) {
+ FileSystemUtils.deleteDir(new File(root, aRelative));
+ }
+
+ /**
+ * Gets the root of the test output directory.
+ *
+ * @return Root of the test output.
+ */
+ public File getRoot() {
+ return root;
+ }
+
+ /**
+ * Gets a file object for a relative path.
+ */
+ public File getFile(String aRelative) {
+ return new File(root, aRelative);
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.io;
import java.io.File;
-
/**
* Test resource for locating resources in the classpath.
*/
public class TestResource extends FileResource {
-
/**
- * Test class name.
- * @param aTestClass Test class.
- * @param aName Name of the file to look for.
+ * Test class name.
+ *
+ * @param aTestClass
+ * Test class.
+ * @param aName
+ * Name of the file to look for.
*/
public TestResource(Class aTestClass, String aName) {
- super(getFile(aTestClass, aName));
+ super(getFile(aTestClass, aName));
}
-
+
/**
- * Computes the file path of the file to look for.
- * @param aClass Test class name.
- * @param aName Name of the file.
- * @return File.
+ * Computes the file path of the file to look for.
+ *
+ * @param aClass
+ * Test class name.
+ * @param aName
+ * Name of the file.
+ * @return File.
*/
- private static File getFile(Class aClass, String aName) {
+ private static File getFile(Class aClass, String aName) {
File dir = FileSystemUtils.getTestInputDir(aClass);
+
return new File(dir, aName);
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.observer;
-import static org.mockito.Mockito.*;
-
-import java.util.ArrayList;
-import java.util.List;
+import junit.framework.TestCase;
import org.mockito.InOrder;
+import static org.mockito.Mockito.*;
-import junit.framework.TestCase;
+import java.util.ArrayList;
+import java.util.List;
/**
* Test of the observer pattern implementation.
* @author Erik Brakkee
*/
public class ObservableTest extends TestCase {
+ private static final int SUBSCRIBER_COUNT = 100;
+ private static final String UPDATE = "send";
+ private Integer observed;
+ private Observable<Integer, String> observable;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ observed = Integer.valueOf(1);
+ observable = new Observable<Integer, String>(observed,
+ new DefaultObserverNotifier());
+ }
+
+ /**
+ * Tests subscription and notification of one subscriber.
+ */
+ public void testOneObserver() {
+ final Observer mockObserver = mock(Observer.class);
+ InOrder order = inOrder(mockObserver);
+
+ long subscription = observable.subscribe(mockObserver);
+
+ assertEquals(1, observable.getObserverCount());
+
+ final String message = "hallo";
+ observable.send(message);
+
+ order.verify(mockObserver).send(observed, message);
+ verifyNoMoreInteractions(mockObserver);
+
+ observable.unsubscribe(subscription);
+ assertEquals(0, observable.getObserverCount());
+
+ observable.send(message);
+ verifyNoMoreInteractions(mockObserver);
+ }
+
+ /**
+ * Subscribes many susbcribers and sends notifications to subscribers.
+ * Verifies that unique subscription number are returned. Also verifies that
+ * the correct subscribers are notfied.
+ */
+ public void testManySubscribers() {
+ final int nsubscribers = SUBSCRIBER_COUNT;
+ final Observer[] mocks = new Observer[nsubscribers];
+ final InOrder[] order = new InOrder[nsubscribers];
+
+ List<Long> subscriptions = new ArrayList<Long>();
+
+ for (int i = 0; i < nsubscribers; i++) {
+ mocks[i] = mock(Observer.class);
+ order[i] = inOrder(mocks[i]);
+
+ long subscription = observable.subscribe(mocks[i]);
+ assertTrue(subscriptions.add(subscription));
+ }
+
+ assertEquals(nsubscribers, observable.getObserverCount());
+
+ final String message = "hallo";
+
+ observable.send(message);
+
+ for (int i = 0; i < nsubscribers; i++) {
+ order[i].verify(mocks[i]).send(observed, message);
+ }
+
+ for (int i = nsubscribers / 2; i < nsubscribers; i++) {
+ observable.unsubscribe(subscriptions.get(i));
+ }
+
+ assertEquals(nsubscribers - (nsubscribers - (nsubscribers / 2)),
+ observable.getObserverCount());
+
+ final String message2 = "blabla";
+
+ observable.send(message2);
+
+ for (int i = 0; i < (nsubscribers / 2); i++) {
+ order[i].verify(mocks[i]).send(observed, message2);
+ }
+
+ for (int i = nsubscribers / 2; i < nsubscribers; i++) {
+ verifyNoMoreInteractions(mocks[i]);
+ }
+ }
+
+ /**
+ * Subscribes and then unsubscribes with a wrong id. Verifies that
+ * IllegalArgumentException is thrown.
+ *
+ */
+ public void testUnsubscribeWithWrongSubscription() {
+ Observer<Integer, String> observer = mock(Observer.class);
+
+ long subscription = observable.subscribe(observer);
+
+ assertEquals(1, observable.getObserverCount());
+
+ try {
+ observable.unsubscribe(subscription + 1);
+ } catch (IllegalArgumentException e) {
+ return; // ok
+ }
- private static final int SUBSCRIBER_COUNT = 100;
-
- private static final String UPDATE = "send";
-
- private Integer _observed;
- private Observable<Integer, String> _observable;
-
- /*
- * (non-Javadoc)
- *
- * @see junit.framework.TestCase#setUp()
- */
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- _observed = new Integer(1);
- _observable = new Observable<Integer, String>(_observed,
- new DefaultObserverNotifier());
- }
-
- /**
- * Tests subscription and notification of one subscriber.
- */
- public void testOneObserver() {
- final Observer mockObserver = mock(Observer.class);
- InOrder order = inOrder(mockObserver);
-
- long subscription = _observable.subscribe(mockObserver);
-
- assertEquals(1, _observable.getObserverCount());
-
- final String message = "hallo";
- _observable.send(message);
-
- order.verify(mockObserver).send(_observed, message);
- verifyNoMoreInteractions(mockObserver);
-
- _observable.unsubscribe(subscription);
- assertEquals(0, _observable.getObserverCount());
-
- _observable.send(message);
- verifyNoMoreInteractions(mockObserver);
- }
-
- /**
- * Subscribes many susbcribers and sends notifications to subscribers.
- * Verifies that unique subscription number are returned. Also verifies that
- * the correct subscribers are notfied.
- */
- public void testManySubscribers() {
- final int nsubscribers = SUBSCRIBER_COUNT;
- final Observer[] mocks = new Observer[nsubscribers];
- final InOrder[] order = new InOrder[nsubscribers];
-
- List<Long> subscriptions = new ArrayList<Long>();
- for (int i = 0; i < nsubscribers; i++) {
- mocks[i] = mock(Observer.class);
- order[i] = inOrder(mocks[i]);
- long subscription = _observable.subscribe(mocks[i]);
- assertTrue(subscriptions.add(subscription));
- }
-
- assertEquals(nsubscribers, _observable.getObserverCount());
-
- final String message = "hallo";
-
- _observable.send(message);
- for (int i = 0; i < nsubscribers; i++) {
- order[i].verify(mocks[i]).send(_observed, message);
- }
-
- for (int i = nsubscribers / 2; i < nsubscribers; i++) {
- _observable.unsubscribe(subscriptions.get(i));
- }
- assertEquals(nsubscribers - (nsubscribers - nsubscribers / 2),
- _observable.getObserverCount());
-
- final String message2 = "blabla";
-
- _observable.send(message2);
- for (int i = 0; i < nsubscribers / 2; i++) {
- order[i].verify(mocks[i]).send(_observed, message2);
- }
- for (int i = nsubscribers/2; i < nsubscribers; i++) {
- verifyNoMoreInteractions(mocks[i]);
- }
-
- }
-
- /**
- * Subscribes and then unsubscribes with a wrong id. Verifies that
- * IllegalArgumentException is thrown.
- *
- */
- public void testUnsubscribeWithWrongSubscription() {
- Observer<Integer, String> observer = mock(Observer.class);
-
- long subscription = _observable.subscribe(observer);
-
- assertEquals(1, _observable.getObserverCount());
-
- try {
- _observable.unsubscribe(subscription + 1);
- } catch (IllegalArgumentException e) {
- return; // ok
- }
- fail();
- }
+ fail();
+ }
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.persistence;
+
+import static junit.framework.Assert.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+import org.junit.Test;
+
+public class JpaMergeSupportTest {
+
+ private static class X1 {
+ @Id
+ int id;
+
+ @Version
+ int version;
+
+ private String value;
+
+ public X1() {
+ value = "";
+ }
+
+ public X1(String aValue) {
+ value = aValue;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object aObj) {
+ if (aObj == null) {
+ return false;
+ }
+ if (!(aObj instanceof X1)) {
+ return false;
+ }
+ return value.equals(((X1) aObj).getValue());
+ }
+ }
+
+ private static class X2 {
+ @Id
+ int id;
+
+ private List<X1> list;
+
+ public X2() {
+ list = new ArrayList<X1>();
+ }
+
+ public List<X1> getList() {
+ return list;
+ }
+ }
+
+ private static class X3 {
+ @Id
+ int id;
+
+ private Set<X1> set;
+
+ public X3() {
+ set = new HashSet<X1>();
+ }
+
+ public Set<X1> getSet() {
+ return set;
+ }
+ }
+
+ private static class X4 {
+ @Id
+ int id;
+
+ private Map<String, X1> map;
+
+ public X4() {
+ map = new HashMap<String, X1>();
+ }
+
+ public Map<String, X1> getMap() {
+ return map;
+ }
+ }
+
+ private static class X5 {
+ @Id
+ int id;
+
+ private X1[] array;
+
+ public X5() {
+ // Empty.
+ }
+
+ public void setArray(X1[] aArray) {
+ array = aArray;
+ }
+
+ public X1[] getArray() {
+ return array;
+ }
+ }
+
+ private static class X6 {
+ @Id
+ int id;
+
+ public X1 getNotaGetter(String aMessage) {
+ return null;
+ }
+
+ public void getNotaGetter2() {
+
+ }
+ }
+
+ private static class X7 {
+ @Id
+ int id;
+
+ private void getX() {
+ fail("Private getters should not be used");
+ }
+ }
+
+ @Test
+ public void testSimple() {
+ X1 x = new X1();
+ x.id = 10;
+ x.version = 20;
+
+ X1 y = new X1();
+
+ JpaMergeSupport.merge(x, y);
+
+ assertEquals(x.id, y.id);
+ assertEquals(x.version, y.version);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSimplePkMismatch() {
+ X1 x = new X1();
+ x.id = 10;
+ x.version = 20;
+
+ X1 y = new X1();
+ y.id = 5;
+ JpaMergeSupport.merge(x, y);
+ }
+
+ @Test
+ public void testTraverseList() {
+ X2 x = new X2();
+ x.id = 10;
+ X1 a = new X1();
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1();
+ b.id = 30;
+ b.version = 31;
+
+ x.getList().add(a);
+ x.getList().add(b);
+
+ X2 y = new X2();
+ y.getList().add(new X1());
+ y.getList().add(new X1());
+
+ JpaMergeSupport.merge(x, y);
+
+ assertEquals(x.id, y.id);
+ assertEquals(x.getList().get(0).id, y.getList().get(0).id);
+ assertEquals(x.getList().get(1).id, y.getList().get(1).id);
+ assertEquals(x.getList().get(0).version, y.getList().get(0).version);
+ assertEquals(x.getList().get(1).version, y.getList().get(1).version);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTraverseListWrongSize() {
+ X2 x = new X2();
+ x.id = 10;
+ X1 a = new X1();
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1();
+ b.id = 30;
+ b.version = 31;
+
+ x.getList().add(a);
+ x.getList().add(b);
+
+ X2 y = new X2();
+ y.getList().add(new X1());
+
+ JpaMergeSupport.merge(x, y);
+ }
+
+ @Test
+ public void testTraverseSet() {
+ X3 x = new X3();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.getSet().add(a);
+ x.getSet().add(b);
+
+ X3 y = new X3();
+ X1 ya = new X1("a");
+ X1 yb = new X1("b");
+
+ y.getSet().add(ya);
+ y.getSet().add(yb);
+ JpaMergeSupport.merge(x, y);
+ assertEquals(x.id, y.id);
+ assertEquals(a.id, ya.id);
+ assertEquals(a.version, ya.version);
+ assertEquals(b.version, yb.version);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTraverseSetWrongSize() {
+ X3 x = new X3();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.getSet().add(a);
+ x.getSet().add(b);
+
+ X3 y = new X3();
+ X1 ya = new X1("a");
+ X1 yb = new X1("b");
+
+ y.getSet().add(ya);
+ JpaMergeSupport.merge(x, y);
+ }
+
+ @Test
+ public void testTraverseMap() {
+ X4 x = new X4();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.getMap().put("a", a);
+ x.getMap().put("b", b);
+
+ X4 y = new X4();
+ X1 ya = new X1("a");
+ X1 yb = new X1("b");
+
+ y.getMap().put("a", ya);
+ y.getMap().put("b", yb);
+ JpaMergeSupport.merge(x, y);
+ assertEquals(x.id, y.id);
+ assertEquals(a.id, ya.id);
+ assertEquals(a.version, ya.version);
+ assertEquals(b.version, yb.version);
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTraverseMapWrongKey() {
+ X4 x = new X4();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.getMap().put("a", a);
+ x.getMap().put("b", b);
+
+ X4 y = new X4();
+ X1 ya = new X1("a");
+ X1 yb = new X1("b");
+
+ y.getMap().put("a", ya);
+ y.getMap().put("c", yb);
+ JpaMergeSupport.merge(x, y);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTraverseMapWrongSize() {
+ X4 x = new X4();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.getMap().put("a", a);
+ x.getMap().put("b", b);
+
+ X4 y = new X4();
+ X1 ya = new X1("a");
+ X1 yb = new X1("b");
+
+ y.getMap().put("a", ya);
+ JpaMergeSupport.merge(x, y);
+ }
+
+ @Test
+ public void testTraverseArray() {
+ X5 x = new X5();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.setArray(new X1[] { a, b });
+
+ X5 y = new X5();
+ X1 ya = new X1("a");
+ X1 yb = new X1("b");
+
+ y.setArray(new X1[] { ya, yb });
+ JpaMergeSupport.merge(x, y);
+ assertEquals(x.id, y.id);
+ assertEquals(a.id, ya.id);
+ assertEquals(a.version, ya.version);
+ assertEquals(b.version, yb.version);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTraverseArrayWrongSize() {
+ X5 x = new X5();
+ x.id = 10;
+ X1 a = new X1("a");
+ a.id = 20;
+ a.version = 21;
+ X1 b = new X1("b");
+ b.id = 30;
+ b.version = 21;
+ x.setArray(new X1[] { a, b });
+
+ X5 y = new X5();
+ X1 ya = new X1("a");
+
+ y.setArray(new X1[] { ya });
+ JpaMergeSupport.merge(x, y);
+ }
+
+ @Test
+ public void testNotAGetter() {
+ X6 x = new X6();
+ x.id = 100;
+ X6 y = new X6();
+
+ JpaMergeSupport.merge(x,y);
+ assertEquals(x.id, y.id);
+ }
+
+ @Test
+ public void testPrivateGetter() {
+ X7 x = new X7();
+ x.id = 100;
+ X7 y = new X7();
+ JpaMergeSupport.merge(x,y);
+ assertEquals(x.id, y.id);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.persistence;
+
+import static junit.framework.Assert.*;
+
+import javax.persistence.Id;
+import javax.persistence.Version;
+
+import org.junit.Test;
+import org.wamblee.persistence.PersistentFactory.Accessor;
+import org.wamblee.persistence.PersistentFactory.EntityAccessor;
+import org.wamblee.persistence.PersistentFactory.EntityObjectAccessor;
+import org.wamblee.persistence.PersistentFactory.FieldAccessor;
+import org.wamblee.persistence.PersistentFactory.PropertyAccessor;
+
+public class PersistentFactoryTest {
+
+ public static class X1 {
+ @Id
+ private int pk;
+
+ public int getPk() {
+ return pk;
+ }
+
+ public void setPk(int aPk) {
+ pk = aPk;
+ }
+
+ private void privateSetter(int aPk) {
+ pk = aPk;
+ }
+
+ private int privateGetter() {
+ return pk;
+ }
+ }
+
+ public static class X2 {
+ private int pk;
+
+ @Id
+ public int getPk() {
+ return pk;
+ }
+
+ public void setPk(int aPk) {
+ pk = aPk;
+ }
+ }
+
+ public static class X3 {
+ private int pk;
+
+ @Id
+ private int getPk() {
+ return pk;
+ }
+
+ private void setPk(int aPk) {
+ pk = aPk;
+ }
+ }
+
+ public static class X4 {
+ @Version
+ private int version;
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int aVersion) {
+ version = aVersion;
+ }
+
+ private void privateSetter(int aVersion) {
+ version = aVersion;
+ }
+
+ private int privateGetter() {
+ return version;
+ }
+ }
+
+ public static class X5 {
+ private int version;
+
+ @Version
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int aVersion) {
+ version = aVersion;
+ }
+ }
+
+ public static class X6 {
+ private int version;
+
+ @Version
+ private int getVersion() {
+ return version;
+ }
+
+ private void setVersion(int aVersion) {
+ version = aVersion;
+ }
+ }
+
+ public static class X7 {
+ @Id
+ public int id;
+
+ @Version
+ public int version;
+ }
+
+ // FieldAccessor test
+
+ @Test
+ public void testFieldAccessorSet() throws Exception {
+ Accessor<Integer> accessor = new FieldAccessor<Integer>(X1.class
+ .getDeclaredField("pk"));
+ X1 x1 = new X1();
+ assertEquals(0, x1.getPk());
+ accessor.set(x1, 10);
+ assertEquals(10, x1.getPk());
+ }
+
+ // PropertyAccessor test
+ @Test
+ public void testPropertyAccessorSet() throws Exception {
+ Accessor<Integer> accessor = new PropertyAccessor<Integer>(X1.class
+ .getDeclaredMethod("getPk"), X1.class.getDeclaredMethod("setPk",
+ int.class));
+ X1 x1 = new X1();
+ assertEquals(0, x1.getPk());
+ accessor.set(x1, 10);
+ assertEquals(10, x1.getPk());
+ }
+
+ @Test
+ public void testPropertyAccessorPrivate() throws Exception {
+ Accessor<Integer> accessor = new PropertyAccessor<Integer>(X1.class
+ .getDeclaredMethod("privateGetter"), X1.class.getDeclaredMethod("privateSetter",
+ int.class));
+ X1 x1 = new X1();
+ assertEquals(0, x1.getPk());
+ accessor.set(x1, 10);
+ assertEquals((Integer)10, accessor.get(x1));
+
+ }
+
+ // EntityAccessor test
+
+ @Test
+ public void testEntityAccessorPkField() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X1.class);
+ assertNotNull(accessor);
+ assertTrue(accessor.getPk() instanceof FieldAccessor);
+ assertNull(accessor.getVersion());
+ assertEquals("pk", ((FieldAccessor) accessor.getPk()).getField()
+ .getName());
+ }
+
+ @Test
+ public void testEntityAccessorPkProperty() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X2.class);
+ assertNotNull(accessor);
+ assertNotNull(accessor.getPk());
+ assertTrue(accessor.getPk() instanceof PropertyAccessor);
+ assertNull(accessor.getVersion());
+ PropertyAccessor property = (PropertyAccessor) accessor.getPk();
+ assertEquals("getPk", property.getGetter().getName());
+ assertEquals("setPk", property.getSetter().getName());
+ }
+
+ @Test
+ public void testEntityAccessorPkPropertyPrivate() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X3.class);
+ assertNotNull(accessor);
+ assertNotNull(accessor.getPk());
+ assertTrue(accessor.getPk() instanceof PropertyAccessor);
+ assertNull(accessor.getVersion());
+ PropertyAccessor property = (PropertyAccessor) accessor.getPk();
+ assertEquals("getPk", property.getGetter().getName());
+ assertEquals("setPk", property.getSetter().getName());
+ }
+
+ @Test
+ public void testEntityAccessorVersionField() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X4.class);
+ assertNotNull(accessor);
+ assertTrue(accessor.getVersion() instanceof FieldAccessor);
+ assertNull(accessor.getPk());
+ assertEquals("version", ((FieldAccessor) accessor.getVersion()).getField()
+ .getName());
+ }
+
+ @Test
+ public void testEntityAccessorVersionProperty() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X5.class);
+ assertNotNull(accessor);
+ assertNotNull(accessor.getVersion());
+ assertTrue(accessor.getVersion() instanceof PropertyAccessor);
+ assertNull(accessor.getPk());
+ PropertyAccessor property = (PropertyAccessor) accessor.getVersion();
+ assertEquals("getVersion", property.getGetter().getName());
+ assertEquals("setVersion", property.getSetter().getName());
+ }
+
+ @Test
+ public void testEntityAccessorVersionPropertyPrivate() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X6.class);
+ assertNotNull(accessor);
+ assertNotNull(accessor.getVersion());
+ assertTrue(accessor.getVersion() instanceof PropertyAccessor);
+ assertNull(accessor.getPk());
+ PropertyAccessor property = (PropertyAccessor) accessor.getVersion();
+ assertEquals("getVersion", property.getGetter().getName());
+ assertEquals("setVersion", property.getSetter().getName());
+ }
+
+ @Test
+ public void testNoVersionAndNoPk() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(String.class);
+ assertNull(accessor);
+ }
+
+ @Test
+ public void testPkAndVersion() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X7.class);
+ assertNotNull(accessor.getPk());
+ assertNotNull(accessor.getVersion());
+
+ X7 x = new X7();
+ assertEquals(0, x.id);
+ assertEquals(0, x.version);
+
+ accessor.getPk().set(x, 10);
+ accessor.getVersion().set(x, 20);
+
+ assertEquals(10, x.id);
+ assertEquals(20, x.version);
+ }
+
+ @Test
+ public void testEntityAccessorCache() {
+ EntityAccessor accessor = PersistentFactory.createEntityAccessor(X1.class);
+ EntityAccessor accessor2 = PersistentFactory.createEntityAccessor(X1.class);
+
+ assertSame(accessor, accessor2);
+ }
+
+ // EntityObjectAccessor test for undefined pk and/or version.
+ @Test
+ public void testEntityObjectAccessorRobustness() {
+ EntityObjectAccessor accessor = new EntityObjectAccessor("hello world",
+ new EntityAccessor(null, null));
+ assertNull(accessor.getPrimaryKey());
+ assertNull(accessor.getPersistedVersion());
+ accessor.setPrimaryKey("bla");
+ accessor.setPersistedVersion(100);
+
+ }
+}
--- /dev/null
+package org.wamblee.reflection;
+
+import static junit.framework.Assert.*;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.Test;
+
+public class ReflectionUtilsTest {
+
+ public static interface X {
+ void x();
+ }
+
+ public static class X2 {
+ private int bla;
+
+ public void x() {
+
+ }
+
+ private void y() {
+
+ }
+ }
+
+ public static class X3 extends X2 {
+ public void z() {
+
+ }
+ }
+
+ public static class X4 extends X2 {
+ public void x() {
+
+ }
+ }
+
+ public static class X5 extends X2 {
+ private String field;
+ private int g;
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetAllMethodsInterface() {
+ ReflectionUtils.getAllMethods(X.class);
+ }
+
+ @Test
+ public void testBasicClass() {
+ List<Method> res = ReflectionUtils.getAllMethods(X2.class, Object.class);
+ assertEquals(2, res.size());
+ }
+
+ @Test
+ public void testInheritanceAdditionalMethod() {
+ List<Method> res = ReflectionUtils.getAllMethods(X3.class, Object.class);
+ assertEquals(3, res.size());
+ }
+
+ @Test
+ public void testInheritanceOverriddenMethod() {
+ List<Method> res = ReflectionUtils.getAllMethods(X4.class, Object.class);
+ assertEquals(2, res.size());
+ for (Method method : res) {
+ if (method.getName().equals("x")) {
+ assertEquals(X4.class, method.getDeclaringClass());
+ }
+ }
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetAllFieldsInterface() {
+ ReflectionUtils.getAllFields(X.class);
+ }
+
+ @Test
+ public void testFieldsFromBasicClass() {
+ List<Field> fields = ReflectionUtils.getAllFields(X2.class);
+ assertEquals(1, fields.size());
+ assertEquals("bla", fields.get(0).getName());
+ }
+
+ public void testFieldsWithInheritance() {
+ List<Field> fields = ReflectionUtils.getAllFields(X5.class);
+ assertEquals(3, fields.size());
+ }
+}
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.test;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.Map.Entry;
import junit.framework.TestCase;
/**
* Useful assertions for use in test cases.
- *
+ *
* @author Erik Brakkee
*/
public final class AssertionUtils {
-
- private static final Log LOG = LogFactory.getLog(AssertionUtils.class);
+ private static final Log LOG = LogFactory.getLog(AssertionUtils.class);
/**
* Disabled constructor.
private AssertionUtils() {
// Empty
}
-
+
/**
* Asserts that two object arrays are equal.
*
public static <T> void assertEquals(T[] aExpected, T[] aActual) {
assertEquals("", aExpected, aActual);
}
-
/**
* Asserts that two object arrays are equal.
* @param aActual
* Actual array.
*/
- public static <T> void assertEquals(String aMsg, T[] aExpected,
- T[] aActual) {
- TestCase.assertEquals(aMsg + " expected " +
- Arrays.asList(aExpected) + ", actual " +
- Arrays.asList(aActual) + ": Array lengths ", aExpected.length,
- aActual.length);
+ public static <T> void assertEquals(String aMsg, T[] aExpected, T[] aActual) {
+ TestCase.assertEquals(aMsg + " expected " + Arrays.asList(aExpected) +
+ ", actual " + Arrays.asList(aActual) + ": Array lengths ",
+ aExpected.length, aActual.length);
for (int i = 0; i < aExpected.length; i++) {
TestCase.assertEquals(aMsg + ": Element " + i, aExpected[i],
- aActual[i]);
+ aActual[i]);
}
}
-
- /**
+/**
* Asserts that two objects are equal, and in case the object is an Object[]
* delegates to {@link #assertEquals(String, Object[], Object[]).
- *
+ *
* @param aMsg
* Message.
* @param aExpected
* @param aActual
* Actual result.
*/
- public static <T> void assertEquals(String aMsg, T aExpected,
- T aActual) {
+ public static <T> void assertEquals(String aMsg, T aExpected, T aActual) {
if (aExpected instanceof Object[]) {
AssertionUtils.assertEquals(aMsg, (Object[]) aExpected,
- (Object[]) aActual);
+ (Object[]) aActual);
return;
}
* @param aActual
* Actual result.
*/
- public static <Key,Value> void assertEquals(String aMsg,
- Map<Key,Value> aExpectedMap, Map<Key,Value> aActual) {
+ public static <Key, Value> void assertEquals(String aMsg,
+ Map<Key, Value> aExpectedMap, Map<Key, Value> aActual) {
TestCase.assertEquals("Map sizes differ", aExpectedMap.size(), aActual
- .size());
+ .size());
- Set keys = aExpectedMap.keySet();
+ Set<Entry<Key,Value>> expectedEntries = aExpectedMap.entrySet();
- for (Iterator i = keys.iterator(); i.hasNext();) {
- String key = (String) i.next();
+ for (Entry<Key,Value> entry: expectedEntries) {
+ Key key = entry.getKey();
TestCase.assertTrue("Map does not containg entry for key:" + key,
- aActual.containsKey(key));
+ aActual.containsKey(key));
AssertionUtils.assertEquals("Value of key " + key + " of map",
- aExpectedMap.get(key), aActual.get(key));
+ entry.getValue(), aActual.get(key));
}
}
-
- public static interface ErroneousCode {
- void run() throws Exception;
- }
-
- /**
+
+ /**
* Asserts that an exception occurs.
- * @param aRunnable Test cases should create a subclass of this which contains the
- * code that should throw an exception.
- * @param aType Type of exception that is expected.
+ *
+ * @param aRunnable
+ * Test cases should create a subclass of this which contains the
+ * code that should throw an exception.
+ * @param aType
+ * Type of exception that is expected.
*/
- public static void assertException(ErroneousCode aObject, Class aType) {
- try {
- aObject.run();
- throw new RuntimeException("No exception occurred");
- } catch (Throwable t) {
- if ( aType.isInstance(t)) {
- LOG.info("Expected exception occured " + t.getMessage());
- return; // ok
- }
- else {
- throw new RuntimeException(t);
- }
- }
+ public static void assertException(ErroneousCode aObject, Class aType) {
+ try {
+ aObject.run();
+ throw new RuntimeException("No exception occurred");
+ } catch (Throwable t) {
+ if (aType.isInstance(t)) {
+ LOG.info("Expected exception occured " + t.getMessage());
+
+ return; // ok
+ } else {
+ throw new RuntimeException(t);
+ }
+ }
+ }
+
+ public static interface ErroneousCode {
+ void run() throws Exception;
}
}
/*
- * Copyright 2006 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.test;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
/**
* Tracks the occurence of certain events in a test environment. Threads in a
* test environment tell the event tracker of the occurrence of certain events
* Type of event sent from test code. Usually String will be
* sufficient. The event type must provide a sensible implementation
* of {@link java.lang.Object#equals(java.lang.Object)}.
- *
+ *
* @author Erik Brakkee
*/
public class EventTracker<Event> {
-
private static final Log LOG = LogFactory.getLog(EventTracker.class);
/**
* Map of Thread object to a list of events.
*/
- private Map<Thread, List<Event>> _events;
+ private Map<Thread, List<Event>> events;
/**
* Constructs the event tracker.
clear();
}
- public void clear() {
- _events = new HashMap<Thread, List<Event>>();
- }
+ public synchronized void clear() {
+ events = new HashMap<Thread, List<Event>>();
+ }
/**
* Called by a thread to inform that an event has occurred.
*/
public synchronized void eventOccurred(Event aEvent) {
LOG.info("Event '" + aEvent + "' sent.");
+
Thread current = Thread.currentThread();
- List<Event> events = _events.get(current);
- if (events == null) {
- events = new ArrayList<Event>();
- _events.put(current, events);
+ List<Event> eventList = events.get(current);
+
+ if (eventList == null) {
+ eventList = new ArrayList<Event>();
+ events.put(current, eventList);
}
- events.add(aEvent);
+
+ eventList.add(aEvent);
}
/**
* @return Whether or not the event was sent.
*/
public synchronized boolean isEventSent(Thread aThread, Event aEvent) {
- List<Event> events = _events.get(aThread);
- if (events == null) {
+ List<Event> eventList = events.get(aThread);
+
+ if (eventList == null) {
return false;
}
- return events.contains(aEvent);
+
+ return eventList.contains(aEvent);
}
/**
* events were sent.
*/
public synchronized List<Event> getEvents(Thread aThread) {
- List<Event> events = _events.get(aThread);
- if (events == null) {
- events = Collections.emptyList();
+ List<Event> eventList = events.get(aThread);
+
+ if (eventList == null) {
+ eventList = Collections.emptyList();
}
- return Collections.unmodifiableList(events);
+
+ return Collections.unmodifiableList(eventList);
}
/**
- * Gets the number of times an event was sent summed up
- * over all threads.
+ * Gets the number of times an event was sent summed up over all threads.
*
* @param aEvent
* Event to check.
*/
public synchronized int getEventCount(Event aEvent) {
int count = 0;
- for (Thread thread : _events.keySet()) {
- List<Event> events = _events.get(thread);
- for (Event event : events) {
+
+ for (Thread thread : events.keySet()) {
+ List<Event> eventList = events.get(thread);
+
+ for (Event event : eventList) {
if (event.equals(aEvent)) {
count++;
}
}
}
+
return count;
}
-
+
/**
- * Gets the total event count over all threads.
+ * Gets the total event count over all threads.
+ *
* @return
*/
- public synchronized int getEventCount() {
- int count = 0;
- for (Thread thread: _events.keySet()) {
- count += _events.get(thread).size();
- }
- return count;
+ public synchronized int getEventCount() {
+ int count = 0;
+
+ for (Thread thread : events.keySet()) {
+ count += events.get(thread).size();
+ }
+
+ return count;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.test;
import junit.framework.TestCase;
/**
* Timing utilities.
- *
+ *
* @author Erik Brakkee
*/
public final class TimingUtils {
-
/**
* Disabled constructor.
- *
+ *
*/
private TimingUtils() {
// Empty
}
-
+
/**
- * Sleeps for a time.
- * @param aMillis Number of milliseconds to sleep.
+ * Sleeps for a time.
+ *
+ * @param aMillis
+ * Number of milliseconds to sleep.
*/
- public static void sleep(int aMillis) {
- try {
+ public static void sleep(int aMillis) {
+ try {
Thread.sleep(aMillis);
- } catch (InterruptedException e) {
+ } catch (InterruptedException e) {
TestCase.fail("Who interrupted my sleep?");
}
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.xml;
+import junit.framework.TestCase;
+
+import org.wamblee.io.ClassPathResource;
+import org.wamblee.io.FileSystemUtils;
+
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
-import junit.framework.TestCase;
-
-
-import org.wamblee.io.ClassPathResource;
-import org.wamblee.io.FileSystemUtils;
-
/**
* Tests for {@link org.wamblee.xml.ClasspathUriResolver}.
- *
+ *
* @author Erik Brakkee
*/
public class ClasspathUriResolverTest extends TestCase {
-
- private URIResolver _resolver;
-
- /* (non-Javadoc)
+ private URIResolver resolver;
+
+ /*
+ * (non-Javadoc)
+ *
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception {
- _resolver = new ClasspathUriResolver();
+ resolver = new ClasspathUriResolver();
}
/**
- * Resolves an existing file. Verifies the file is resolved correctly.
- * @throws TransformerException
+ * Resolves an existing file. Verifies the file is resolved correctly.
+ *
+ * @throws TransformerException
* @throws IOException
*/
- public void testResolveExistingFile() throws TransformerException, IOException {
- Source source = _resolver.resolve("org/wamblee/xml/reportToHtml.xsl", "");
+ public void testResolveExistingFile() throws TransformerException,
+ IOException {
+ Source source = resolver
+ .resolve("org/wamblee/xml/reportToHtml.xsl", "");
assertTrue(source instanceof StreamSource);
- String resolved = FileSystemUtils.read(((StreamSource)source).getInputStream());
-
- ClassPathResource resource = new ClassPathResource("org/wamblee/xml/reportToHtml.xsl");
+
+ String resolved = FileSystemUtils.read(((StreamSource) source)
+ .getInputStream());
+
+ ClassPathResource resource = new ClassPathResource(
+ "org/wamblee/xml/reportToHtml.xsl");
String expected = FileSystemUtils.read(resource.getInputStream());
assertEquals(expected, resolved);
}
-
+
/**
- * Resolves a non-existing file. Verifies that a TransformerException is thrown.
- *
+ * Resolves a non-existing file. Verifies that a TransformerException is
+ * thrown.
+ *
*/
public void testResolveNonExistingFile() {
- try {
- Source source = _resolver.resolve("org/wamblee/xml/reportToHtml-nonexisting.xsl", "");
- } catch (TransformerException e) {
+ try {
+ resolver.resolve(
+ "org/wamblee/xml/reportToHtml-nonexisting.xsl", "");
+ } catch (TransformerException e) {
return; // ok
}
+
fail();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.xml;
+import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* XML test support utilities.
- *
+ *
* @author Erik Brakkee
*/
public final class XmlUtils {
-
/**
* Disabled constructor.
*
/**
* Checks equality of two XML documents excluding comment and processing
* nodes and trimming the text of the elements. In case of problems, it
- * provides an xpath-like expression describing where the problem is.
+ * provides an xpath-like expression describing where the problem is.
*
* @param aMsg
* @param aExpected
* @param aActual
*/
public static void assertEquals(String aMsg,
- org.w3c.dom.Document aExpected, org.w3c.dom.Document aActual) {
+ org.w3c.dom.Document aExpected, org.w3c.dom.Document aActual) {
assertEquals(aMsg, DomUtils.convert(aExpected), DomUtils
- .convert(aActual));
+ .convert(aActual));
}
/**
* Checks equality of two XML documents excluding comment and processing
- * nodes and trimming the text of the elements. In case of problems, it
- * provides an xpath-like expression describing where the problem is.
+ * nodes and trimming the text of the elements. In case of problems, it
+ * provides an xpath-like expression describing where the problem is.
*
* @param aMsg
* @param aExpected
* @param aActual
*/
public static void assertEquals(String aMsg, Document aExpected,
- Document aActual) {
- assertEquals(aMsg + "/" + aExpected.getRootElement().getName(), aExpected.getRootElement(), aActual.getRootElement());
+ Document aActual) {
+ assertEquals(aMsg + "/" + aExpected.getRootElement().getName(),
+ aExpected.getRootElement(), aActual.getRootElement());
}
/**
* Checks equality of two XML elements excluding comment and processing
* nodes and trimming the text of the elements. In case of problems, it
- * provides an xpath-like expression describing where the problem is.
+ * provides an xpath-like expression describing where the problem is.
*
* @param aMsg
* @param aExpected
* @param aActual
*/
public static void assertEquals(String aMsg, Element aExpected,
- Element aActual) {
-
+ Element aActual) {
// Name.
TestCase.assertEquals(aMsg + "/name()", aExpected.getName(), aActual
- .getName());
+ .getName());
// Text
TestCase.assertEquals(aMsg + "/text()", aExpected.getTextTrim(),
- aActual.getTextTrim());
+ aActual.getTextTrim());
// Attributes
List<Attribute> expectedAttrs = aExpected.attributes();
Collections.sort(expectedAttrs, new AttributeComparator());
+
List<Attribute> actualAttrs = aActual.attributes();
Collections.sort(actualAttrs, new AttributeComparator());
TestCase.assertEquals("count(" + aMsg + "/@*)", expectedAttrs.size(),
- actualAttrs.size());
+ actualAttrs.size());
+
for (int i = 0; i < expectedAttrs.size(); i++) {
String msg = aMsg + "/@" + expectedAttrs.get(i).getName();
assertEquals(msg, expectedAttrs.get(i), actualAttrs.get(i));
List<Element> expectedElems = aExpected.elements();
List<Element> actualElems = aActual.elements();
TestCase.assertEquals("count(" + aMsg + "/*)", expectedElems.size(),
- actualElems.size());
+ actualElems.size());
+
// determine the how-manyth element of the given name we are at.
// Maps element name to the last used index (or null if not yet used)
Map<String, Integer> elementIndex = new TreeMap<String, Integer>();
+
for (int i = 0; i < expectedElems.size(); i++) {
String elemName = expectedElems.get(i).getName();
Integer index = elementIndex.get(elemName);
+
if (index == null) {
index = 1;
} else {
index++;
}
+
elementIndex.put(elemName, index);
- String msg = aMsg + "/" + expectedElems.get(i).getName() + "["
- + index + "]";
+
+ String msg = aMsg + "/" + expectedElems.get(i).getName() + "[" +
+ index + "]";
assertEquals(msg, expectedElems.get(i), actualElems.get(i));
}
}
/**
- * Checks equality of two attributes. In case of problems, it
- * provides an xpath-like expression describing where the problem is.
+ * Checks equality of two attributes. In case of problems, it provides an
+ * xpath-like expression describing where the problem is.
*
* @param aMsg
* @param aExpected
* @param aActual
*/
public static void assertEquals(String aMsg, Attribute aExpected,
- Attribute aActual) {
+ Attribute aActual) {
TestCase.assertEquals(aMsg + ":name", aExpected.getName(), aActual
- .getName());
+ .getName());
TestCase.assertEquals(aMsg + ":value", aExpected.getValue(), aActual
- .getValue());
+ .getValue());
}
/**
* Comparator which compares attributes by name.
*/
private static final class AttributeComparator implements
- Comparator<Attribute> {
+ Comparator<Attribute>, Serializable {
+
+ private static final long serialVersionUID = 7897287273519886301L;
+
/*
* (non-Javadoc)
*
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.xml;
import java.io.ByteArrayOutputStream;
-import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.stream.StreamSource;
import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
import org.wamblee.io.ClassPathResource;
import org.wamblee.io.FileSystemUtils;
import org.wamblee.io.InputResource;
-import org.w3c.dom.Document;
-
/**
* Tests the XSL transformer.
- *
+ *
* @author Erik Brakkee
*/
public class XslTransformerTest extends TestCase {
-
private static final String INCLUDED_XSL_FILE = "utilities.xsl";
-
- private static final String REPORT_XML = "report.xml";
-
+ private static final String REPORT_XML = "report.xml";
private static final String REPORT_TO_HTML_XSLT = "reportToHtml.xsl";
-
private static final String REPORT_TO_HTML2_XSLT = "reportToHtml2.xsl";
-
private static final String REPORT_TO_HTML_INVALID_XSLT = "reportToHtml-invalid.xsl";
-
private static final String REPORT_TO_HTML_NONWELLFORMED_XSLT = "reportToHtml-nonwellformed.xsl";
-
private static final String REPORT_TO_TEXT_XSLT = "reportToText.xsl";
- private String getResourcePath(String aResource) {
- return getClass().getPackage().getName().replaceAll("\\.", "/") + "/" + aResource;
+ private String getResourcePath(String aResource) {
+ return getClass().getPackage().getName().replaceAll("\\.", "/") + "/" +
+ aResource;
}
/**
public void testTransformUsingDefaultResolver() throws Exception {
XslTransformer transformer = new XslTransformer();
- InputResource xmlResource = new ClassPathResource(getResourcePath(REPORT_XML));
-
- Source xslt = new StreamSource(new ClassPathResource(getResourcePath(
- REPORT_TO_HTML_XSLT)).getInputStream());
+ InputResource xmlResource = new ClassPathResource(
+ getResourcePath(REPORT_XML));
+
+ Source xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML_XSLT)).getInputStream());
byte[] documentData = FileSystemUtils
- .read(xmlResource.getInputStream()).getBytes();
+ .read(xmlResource.getInputStream()).getBytes();
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
- .newDocumentBuilder();
+ .newDocumentBuilder();
Document document = builder.parse(xmlResource.getInputStream());
Source documentSource = new StreamSource(xmlResource.getInputStream());
- Document expected = DomUtils.read(new ClassPathResource(getResourcePath(
- "output-reportToHtml-report.xml")).getInputStream());
+ Document expected = DomUtils
+ .read(new ClassPathResource(
+ getResourcePath("output-reportToHtml-report.xml"))
+ .getInputStream());
Document output1 = transformer.transform(documentData, xslt);
XmlUtils.assertEquals("byte[] transform", expected, output1);
- xslt = new StreamSource(new ClassPathResource(getResourcePath(
- REPORT_TO_HTML_XSLT)).getInputStream());
+ xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML_XSLT)).getInputStream());
+
Document output2 = transformer.transform(document, xslt);
XmlUtils.assertEquals("document transform", expected, output2);
ByteArrayOutputStream os = new ByteArrayOutputStream();
Result output = new StreamResult(os);
-
- xslt = new StreamSource(new ClassPathResource(getResourcePath(
- REPORT_TO_HTML_XSLT)).getInputStream());
+
+ xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML_XSLT)).getInputStream());
transformer.transform(documentSource, output, xslt);
XmlUtils.assertEquals("document source transform", expected, DomUtils
- .read(os.toString()));
+ .read(os.toString()));
+
+ xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML_XSLT)).getInputStream());
- xslt = new StreamSource(new ClassPathResource(getResourcePath(
- REPORT_TO_HTML_XSLT)).getInputStream());
String result = transformer.textTransform(documentData, xslt);
XmlUtils
- .assertEquals("text transform", expected, DomUtils.read(result));
+ .assertEquals("text transform", expected, DomUtils.read(result));
}
/**
public void testTransformUsingDefaultResolverFails() throws IOException {
XslTransformer transformer = new XslTransformer();
- InputResource xmlResource =
- new ClassPathResource(getResourcePath(REPORT_XML));
- Source xslt = new StreamSource(
- new ClassPathResource(getResourcePath(
- REPORT_TO_HTML2_XSLT)).getInputStream());
+ InputResource xmlResource = new ClassPathResource(
+ getResourcePath(REPORT_XML));
+ Source xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML2_XSLT)).getInputStream());
byte[] documentData = FileSystemUtils
- .read(xmlResource.getInputStream()).getBytes();
+ .read(xmlResource.getInputStream()).getBytes();
+
try {
- Document output1 = transformer.transform(documentData, xslt);
+ transformer.transform(documentData, xslt);
} catch (TransformerException e) {
return; // ok
}
+
fail();
}
XslTransformer transformer = new XslTransformer();
InputResource xmlResource = new ClassPathResource(
- getResourcePath(REPORT_XML));
- Source xslt = new StreamSource(
- new ClassPathResource(getResourcePath(REPORT_TO_HTML_INVALID_XSLT)).getInputStream());
+ getResourcePath(REPORT_XML));
+ Source xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML_INVALID_XSLT)).getInputStream());
byte[] documentData = FileSystemUtils
- .read(xmlResource.getInputStream()).getBytes();
+ .read(xmlResource.getInputStream()).getBytes();
+
try {
- Document output1 = transformer.transform(documentData, xslt);
+ transformer.transform(documentData, xslt);
} catch (TransformerException e) {
return; // ok
}
+
fail();
}
XslTransformer transformer = new XslTransformer();
InputResource xmlResource = new ClassPathResource(
- getResourcePath(REPORT_XML));
- Source xslt = new StreamSource(
- new ClassPathResource(getResourcePath(
- REPORT_TO_HTML_NONWELLFORMED_XSLT)).getInputStream());
+ getResourcePath(REPORT_XML));
+ Source xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_HTML_NONWELLFORMED_XSLT))
+ .getInputStream());
byte[] documentData = FileSystemUtils
- .read(xmlResource.getInputStream()).getBytes();
+ .read(xmlResource.getInputStream()).getBytes();
+
try {
- Document output1 = transformer.transform(documentData, xslt);
+ transformer.transform(documentData, xslt);
} catch (TransformerException e) {
return; // ok
}
+
fail();
}
*
*/
public void testTransformUsingClassPathResolver() throws Exception {
- XslTransformer transformer = new XslTransformer(new ClasspathUriResolver());
+ XslTransformer transformer = new XslTransformer(
+ new ClasspathUriResolver());
- InputResource xmlResource = new ClassPathResource(getResourcePath(
- REPORT_XML));
+ InputResource xmlResource = new ClassPathResource(
+ getResourcePath(REPORT_XML));
Source xslt = new StreamSource(new ClassPathResource(
- getResourcePath(REPORT_TO_HTML2_XSLT)).getInputStream());
+ getResourcePath(REPORT_TO_HTML2_XSLT)).getInputStream());
byte[] documentData = FileSystemUtils
- .read(xmlResource.getInputStream()).getBytes();
-
+ .read(xmlResource.getInputStream()).getBytes();
+
Document output1 = transformer.transform(documentData, xslt);
- Document expected = DomUtils.read(new ClassPathResource(
- getResourcePath("output-reportToHtml-report.xml"))
+ Document expected = DomUtils
+ .read(new ClassPathResource(
+ getResourcePath("output-reportToHtml-report.xml"))
.getInputStream());
XmlUtils.assertEquals("doc", expected, output1);
}
*
*/
public void testTransformToTextOutput() throws Exception {
- XslTransformer transformer = new XslTransformer(new ClasspathUriResolver());
+ XslTransformer transformer = new XslTransformer(
+ new ClasspathUriResolver());
InputResource xmlResource = new ClassPathResource(
- getResourcePath(REPORT_XML));
- Source xslt = new StreamSource(
- new ClassPathResource(getResourcePath(REPORT_TO_TEXT_XSLT)).getInputStream());
+ getResourcePath(REPORT_XML));
+ Source xslt = new StreamSource(new ClassPathResource(
+ getResourcePath(REPORT_TO_TEXT_XSLT)).getInputStream());
byte[] documentData = FileSystemUtils
- .read(xmlResource.getInputStream()).getBytes();
-
+ .read(xmlResource.getInputStream()).getBytes();
+
String result = transformer.textTransform(documentData, xslt);
String expected = "Hello world!";
assertEquals("text transform", expected, result);
}
-
+
/**
- * Tests resolving a file using {@link XslTransformer#resolve(String)} with the
- * default resolver where the file does not exist.
- *
+ * Tests resolving a file using {@link XslTransformer#resolve(String)} with
+ * the default resolver where the file does not exist.
+ *
*/
- public void testResolveWithDefaultResolverFileNotFound() {
+ public void testResolveWithDefaultResolverFileNotFound() {
XslTransformer transformer = new XslTransformer();
- try {
- Source source = transformer.resolve("org/wamblee/xml/utilities-nonexistent.xsl");
- } catch (TransformerException e) {
+
+ try {
+ transformer
+ .resolve("org/wamblee/xml/utilities-nonexistent.xsl");
+ } catch (TransformerException e) {
return; // ok
}
+
fail();
}
-
-
+
/**
- * Tests resolving a file using {@link XslTransformer#resolve(String)} with the
- * default resolver.
- *
+ * Tests resolving a file using {@link XslTransformer#resolve(String)} with
+ * the default resolver.
+ *
*/
- public void testResolveWithClasspathResolver() throws Exception {
- XslTransformer transformer = new XslTransformer(new ClasspathUriResolver());
+ public void testResolveWithClasspathResolver() throws Exception {
+ XslTransformer transformer = new XslTransformer(
+ new ClasspathUriResolver());
Source source = transformer.resolve(getResourcePath(INCLUDED_XSL_FILE));
- assert(source instanceof StreamSource);
- StreamSource ssource = (StreamSource)source;
+ assert (source instanceof StreamSource);
+
+ StreamSource ssource = (StreamSource) source;
String data = FileSystemUtils.read(ssource.getInputStream());
- String expected = FileSystemUtils.read(new ClassPathResource(getResourcePath(INCLUDED_XSL_FILE)).getInputStream());
+ String expected = FileSystemUtils.read(new ClassPathResource(
+ getResourcePath(INCLUDED_XSL_FILE)).getInputStream());
assertEquals(expected, data);
}
-
}
-
-
<artifactId>hibernate</artifactId>
</exclusion>
</exclusions>
- </dependency>
- <dependency>
- <groupId>org.wamblee</groupId>
- <artifactId>wamblee-hibernate-jpa</artifactId>
- <version>0.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.concurrency.spring;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
+
import org.wamblee.concurrency.Lock;
/**
- * Locking advice. This automatically synchronized an object using a given lock.
- *
+ * Locking advice. This automatically synchronized an object using a given lock.
+ *
* @author Erik Brakkee
*/
public class LockAdvice implements MethodInterceptor {
-
/**
- * Lock to use.
+ * Lock to use.
*/
- private Lock _lock;
-
+ private Lock lock;
+
/**
- * Constructs lock advice.
- * @param aLock Lock to use.
+ * Constructs lock advice.
+ *
+ * @param aLock
+ * Lock to use.
*/
- public LockAdvice(Lock aLock) {
- _lock = aLock;
+ public LockAdvice(Lock aLock) {
+ lock = aLock;
}
-
- /* (non-Javadoc)
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept
+ * .MethodInvocation)
*/
public Object invoke(MethodInvocation aInvocation) throws Throwable {
- _lock.acquire();
- try {
- return aInvocation.proceed();
- } finally {
- _lock.release();
+ lock.acquire();
+
+ try {
+ return aInvocation.proceed();
+ } finally {
+ lock.release();
}
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.general.spring;
import org.springframework.beans.BeansException;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
import org.wamblee.general.BeanFactory;
import org.wamblee.general.BeanFactoryException;
-import org.wamblee.general.BeanKernel;
/**
* Bean factory which uses Spring. This bean factory cannot be configured
* it must tbe subclassed to provide a default constructor.
*/
public class SpringBeanFactory implements BeanFactory {
-
- private BeanFactoryReference _factoryReference;
+ private BeanFactoryReference factoryReference;
/**
* Constructs the bean factory.
public SpringBeanFactory(String aSelector, String aFactoryName) {
try {
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator
- .getInstance(aSelector);
- _factoryReference = locator.useBeanFactory(aFactoryName);
+ .getInstance(aSelector);
+ factoryReference = locator.useBeanFactory(aFactoryName);
} catch (BeansException e) {
throw new BeanFactoryException(
- "Could not load bean factory: selector = '" + aSelector
- + "', factory = '" + aFactoryName + "'", e);
+ "Could not load bean factory: selector = '" + aSelector +
+ "', factory = '" + aFactoryName + "'", e);
}
}
* (non-Javadoc)
*
* @see org.wamblee.general.BeanFactory#find(java.lang.String,
- * java.lang.Class)
+ * java.lang.Class)
*/
public <T> T find(String aId, Class<T> aClass) {
try {
- Object obj = _factoryReference.getFactory().getBean(aId, aClass);
+ Object obj = factoryReference.getFactory().getBean(aId, aClass);
assert obj != null;
+
return aClass.cast(obj);
} catch (BeansException e) {
throw new BeanFactoryException(e.getMessage(), e);
}
}
-
+
/**
- * Gets the spring bean factory.
- * @return Spring bean factory.
+ * Gets the spring bean factory.
+ *
+ * @return Spring bean factory.
*/
- public org.springframework.beans.factory.BeanFactory getSpringBeanFactory() {
- return _factoryReference.getFactory();
+ public org.springframework.beans.factory.BeanFactory getSpringBeanFactory() {
+ return factoryReference.getFactory();
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.persistence.hibernate;
import java.util.ArrayList;
import java.util.Arrays;
/**
- * Hibernate mapping files to use.
- *
+ * Hibernate mapping files to use.
+ *
* @author Erik Brakkee
*/
public class HibernateMappingFiles extends ArrayList<String> {
-
/**
- * Constructs an empty list of hibernate mapping files.
- *
+ * Constructs an empty list of hibernate mapping files.
+ *
*/
- public HibernateMappingFiles() {
- super();
+ public HibernateMappingFiles() {
+ super();
}
-
+
/**
- * Constructs the list of Spring config files.
- * @param aFiles Files.
+ * Constructs the list of Spring config files.
+ *
+ * @param aFiles
+ * Files.
*/
- public HibernateMappingFiles(String[] aFiles) {
- super();
+ public HibernateMappingFiles(String[] aFiles) {
+ super();
addAll(Arrays.asList(aFiles));
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.persistence.hibernate;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Extension of
* {@link org.springframework.orm.hibernate.support.HibernateDaoSupport}.
- *
+ *
* @author Erik Brakkee
*/
public class HibernateSupport extends HibernateDaoSupport {
-
private static final Log LOG = LogFactory.getLog(HibernateSupport.class);
- /**
- * This class provided an equality operation based on the object reference
- * of the wrapped object. This is required because we cannto assume that the
- * equals operation has any meaning for different types of persistent
- * objects. This allows us to use the standard collection classes for
- * detecting cyclic dependences and avoiding recursion.
- *
- */
- private static final class ObjectElem {
- private Object _object;
-
- public ObjectElem(Object aObject) {
- _object = aObject;
- }
-
- public boolean equals(Object aObj) {
- return ((ObjectElem) aObj)._object == _object;
- }
-
- public int hashCode() {
- return _object.hashCode();
- }
- }
-
/**
* Constructs the object.
*
}
/**
- * Performes a hibernate <code>Session.merge()</code> and updates the
- * object with the correct primary key and version. This is an extension to
- * the hibernate merge operation because hibernate itself leaves the object
- * passed to merge untouched.
- *
- * Use this method with extreme caution since it will recursively load all
- * objects that the current object has relations with and for which
- * cascade="merge" was specified in the Hibernate mapping file.
+ * Performes a hibernate <code>Session.merge()</code> and updates the object
+ * with the correct primary key and version. This is an extension to the
+ * hibernate merge operation because hibernate itself leaves the object
+ * passed to merge untouched. Use this method with extreme caution since it
+ * will recursively load all objects that the current object has relations
+ * with and for which cascade="merge" was specified in the Hibernate mapping
+ * file.
*
* @param aPersistent
* Object to merge.
* @param aProcessed
* List of already processed Persistent objects of the persistent
* part.
+ *
*/
public static void processPersistent(Persistent aPersistent,
- Persistent aMerged, List<ObjectElem> aProcessed) {
- if (aPersistent == null && aMerged == null) {
+ Persistent aMerged, List<ObjectElem> aProcessed) {
+ if ((aPersistent == null) && (aMerged == null)) {
return;
}
- if (aPersistent == null || aMerged == null) {
- throw new RuntimeException("persistent or merged object is null '"
- + aPersistent + "'" + " '" + aMerged + "'");
+
+ if ((aPersistent == null) || (aMerged == null)) {
+ throw new RuntimeException("persistent or merged object is null '" +
+ aPersistent + "'" + " '" + aMerged + "'");
}
+
ObjectElem elem = new ObjectElem(aPersistent);
+
if (aProcessed.contains(elem)) {
return; // already processed.
}
+
aProcessed.add(elem);
LOG.debug("Setting pk/version on " + aPersistent + " from " + aMerged);
- if (aPersistent.getPrimaryKey() != null
- && !aMerged.getPrimaryKey().equals(aPersistent.getPrimaryKey())) {
- LOG.error("Mismatch between primary key values: " + aPersistent
- + " " + aMerged);
+ if ((aPersistent.getPrimaryKey() != null) &&
+ !aMerged.getPrimaryKey().equals(aPersistent.getPrimaryKey())) {
+ LOG.error("Mismatch between primary key values: " + aPersistent +
+ " " + aMerged);
} else {
aPersistent.setPersistedVersion(aMerged.getPersistedVersion());
aPersistent.setPrimaryKey(aMerged.getPrimaryKey());
}
Method[] methods = aPersistent.getClass().getMethods();
+
for (Method getter : methods) {
if (getter.getName().startsWith("get")) {
Class returnType = getter.getReturnType();
} else if (Persistent.class.isAssignableFrom(returnType)) {
Persistent merged = (Persistent) getter.invoke(aMerged);
Persistent persistent = (Persistent) getter
- .invoke(aPersistent);
+ .invoke(aPersistent);
processPersistent(persistent, merged, aProcessed);
- } else if (returnType.isArray()
- && Persistent.class.isAssignableFrom(returnType
- .getComponentType())) {
+ } else if (returnType.isArray() &&
+ Persistent.class.isAssignableFrom(returnType
+ .getComponentType())) {
Persistent[] merged = (Persistent[]) getter
- .invoke(aMerged);
+ .invoke(aMerged);
Persistent[] persistent = (Persistent[]) getter
- .invoke(aPersistent);
+ .invoke(aPersistent);
+
for (int i = 0; i < persistent.length; i++) {
processPersistent(persistent[i], merged[i],
- aProcessed);
+ aProcessed);
}
}
} catch (InvocationTargetException e) {
}
}
}
-
}
/**
* Collection as a result of the merge.
* @param aProcessed
* List of processed persistent objects.
+ *
*/
public static void processList(List aPersistent, List aMerged,
- List<ObjectElem> aProcessed) {
+ List<ObjectElem> aProcessed) {
Object[] merged = aMerged.toArray();
Object[] persistent = aPersistent.toArray();
+
if (merged.length != persistent.length) {
- throw new RuntimeException("Array sizes differ " + merged.length
- + " " + persistent.length);
+ throw new RuntimeException("Array sizes differ " + merged.length +
+ " " + persistent.length);
}
+
for (int i = 0; i < merged.length; i++) {
assert merged[i].equals(persistent[i]);
+
if (merged[i] instanceof Persistent) {
processPersistent((Persistent) persistent[i],
- (Persistent) merged[i], aProcessed);
+ (Persistent) merged[i], aProcessed);
}
}
}
* Collection as a result of the merge.
* @param aProcessed
* List of processed persistent objects.
+ *
*/
public static void processSet(Set aPersistent, Set aMerged,
- List<ObjectElem> aProcessed) {
+ List<ObjectElem> aProcessed) {
if (aMerged.size() != aPersistent.size()) {
- throw new RuntimeException("Array sizes differ " + aMerged.size()
- + " " + aPersistent.size());
+ throw new RuntimeException("Array sizes differ " + aMerged.size() +
+ " " + aPersistent.size());
}
+
for (Object merged : aMerged) {
// Find the object that equals the merged[i]
for (Object persistent : aPersistent) {
if (persistent.equals(merged)) {
processPersistent((Persistent) persistent,
- (Persistent) merged, aProcessed);
+ (Persistent) merged, aProcessed);
+
break;
}
}
* Collection as a result of the merge.
* @param aProcessed
* List of processed persistent objects.
+ *
*/
- public static void processMap(Map aPersistent, Map aMerged,
- List<ObjectElem> aProcessed) {
+ public static <Key,Value> void processMap(Map<Key,Value> aPersistent, Map<Key,Value> aMerged,
+ List<ObjectElem> aProcessed) {
if (aMerged.size() != aPersistent.size()) {
- throw new RuntimeException("Sizes differ " + aMerged.size() + " "
- + aPersistent.size());
+ throw new RuntimeException("Sizes differ " + aMerged.size() + " " +
+ aPersistent.size());
}
- Set keys = aMerged.keySet();
- for (Object key : keys) {
+
+ Set<Entry<Key,Value>> entries = aMerged.entrySet();
+
+ for (Entry<Key,Value> entry : entries) {
+ Key key = entry.getKey();
if (!aPersistent.containsKey(key)) {
throw new RuntimeException("Key '" + key + "' not found");
}
- Object mergedValue = aMerged.get(key);
+
+ Value mergedValue = entry.getValue();
Object persistentValue = aPersistent.get(key);
+
if (mergedValue instanceof Persistent) {
if (persistentValue instanceof Persistent) {
processPersistent((Persistent) persistentValue,
- (Persistent) mergedValue, aProcessed);
+ (Persistent) mergedValue, aProcessed);
} else {
throw new RuntimeException(
- "Value in original object is null, whereas merged object contains a value");
+ "Value in original object is null, whereas merged object contains a value");
}
}
}
}
+ /**
+ * This class provided an equality operation based on the object reference
+ * of the wrapped object. This is required because we cannto assume that the
+ * equals operation has any meaning for different types of persistent
+ * objects. This allows us to use the standard collection classes for
+ * detecting cyclic dependences and avoiding recursion.
+ */
+ private static final class ObjectElem {
+ private Object object;
+
+ public ObjectElem(Object aObject) {
+ object = aObject;
+ }
+
+ public boolean equals(Object aObj) {
+ if (aObj == null) {
+ return false;
+ }
+ if (!(aObj instanceof ObjectElem)) {
+ return false;
+ }
+ return ((ObjectElem) aObj).object == object;
+ }
+
+ public int hashCode() {
+ return object.hashCode();
+ }
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.concurrency.spring;
import org.springframework.aop.framework.ProxyFactoryBean;
+
import org.wamblee.concurrency.AbstractLockTestCase;
import org.wamblee.concurrency.JvmLock;
import org.wamblee.concurrency.spring.LockAdvice;
+
import org.wamblee.test.TimingUtils;
/**
*
- *
* @author Erik Brakkee
*/
public class LockAdviceTest extends AbstractLockTestCase {
-
- private class Runner implements Runnable {
- public void run() {
- LockAdviceTest.this.getTracker().eventOccurred(ACQUIRED);
- TimingUtils.sleep(SLEEP_TIME);
- }
- }
-
- private Runnable _target;
+ private Runnable target;
/*
* (non-Javadoc)
@Override
protected void setUp() throws Exception {
super.setUp();
-
+
Runner runner = new Runner();
LockAdvice advice = new LockAdvice(new JvmLock());
-
+
ProxyFactoryBean support = new ProxyFactoryBean();
- support.setInterfaces(new Class[]{ Runnable.class });
+ support.setInterfaces(new Class[] { Runnable.class });
support.setTarget(runner);
support.addAdvice(advice);
- _target = (Runnable)support.getObject();
-
+ target = (Runnable) support.getObject();
}
/*
public void run() {
try {
getTracker().eventOccurred(STARTED);
- _target.run();
+ target.run();
getTracker().eventOccurred(RELEASED);
} catch (Throwable e) {
throw new RuntimeException(e);
};
});
t.start();
+
return t;
}
+ private class Runner implements Runnable {
+ public void run() {
+ LockAdviceTest.this.getTracker().eventOccurred(ACQUIRED);
+ TimingUtils.sleep(SLEEP_TIME);
+ }
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.general.spring;
-import org.wamblee.general.BeanFactoryException;
-
import junit.framework.TestCase;
+import org.wamblee.general.BeanFactoryException;
+
/**
* Tests the spring bean factory.
- *
+ *
* @author Erik Brakkee
*/
public class SpringBeanFactoryTest extends TestCase {
-
/*
* (non-Javadoc)
*
@Override
protected void setUp() throws Exception {
super.setUp();
-
}
public void testExistingBeanRefContext() {
SpringBeanFactory factory = new SpringBeanFactory(
- "org/wamblee/general/beanRefContext.xml", "test");
+ "org/wamblee/general/beanRefContext.xml", "test");
String value1 = factory.find(String.class);
assertEquals("hello", value1);
+
String value2 = (String) factory.find("java.lang.String");
assertEquals("hello", value2);
+
String value3 = factory.find("java.lang.String", String.class);
assertEquals("hello", value3);
} catch (BeanFactoryException e) {
return; // ok
}
+
fail();
}
public void testUnknownBeanFactory() {
try {
- new SpringBeanFactory(
- "org/wamblee/general/beanRefContext.xml", "unknown");
+ new SpringBeanFactory("org/wamblee/general/beanRefContext.xml",
+ "unknown");
} catch (BeanFactoryException e) {
return; // ok
}
+
fail();
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.general.spring;
/**
* Test bean factory.
- *
+ *
* @author Erik Brakkee
*/
public class TestBeanFactory extends SpringBeanFactory {
-
-
- public TestBeanFactory() {
+ /**
+ * Creates a new TestBeanFactory object.
+ */
+ public TestBeanFactory() {
super("org/wamblee/general/beanRefContext.xml", "test");
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.wamblee.test.spring;
-import java.io.File;
-import java.io.IOException;
-
import org.hibernate.cfg.Configuration;
+
import org.hibernate.tool.hbm2ddl.SchemaExport;
+import java.io.File;
+import java.io.IOException;
+
/**
- * Exporting the hibernate mapping.
- *
+ * Exporting the hibernate mapping.
+ *
* @author Erik Brakkee
*/
public final class HibernateExporter {
-
/**
* Disabled constructor.
- *
+ *
*/
- private HibernateExporter() {
+ private HibernateExporter() {
// Empty
}
-
+
public static void main(String[] aArgs) throws IOException {
String file = aArgs[0];
- File dir = new File(aArgs[1]);
-
+ File dir = new File(aArgs[1]);
+
Configuration conf = HibernateUtils.getConfiguration(dir);
-
+
SchemaExport export = new SchemaExport(conf);
export.setDelimiter(";");
- export.setOutputFile(file);
+ export.setOutputFile(file);
export.create(true, false);
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.test.spring;
-import java.io.File;
-import java.io.IOException;
-
import org.hibernate.cfg.Configuration;
+
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
+import java.io.File;
+import java.io.IOException;
+
/**
* Exporting the hibernate mapping.
- *
+ *
* @author Erik Brakkee
*/
public final class HibernateUpdater {
-
/**
* Disabled constructor.
- *
+ *
*/
- private HibernateUpdater() {
+ private HibernateUpdater() {
// Empty
}
SchemaUpdate lSchemaUpdate = new SchemaUpdate(conf);
lSchemaUpdate.execute(true, true);
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.test.spring;
+import org.apache.oro.io.AwkFilenameFilter;
+
+import org.hibernate.cfg.Configuration;
+
+import org.wamblee.io.ClassPathResource;
+import org.wamblee.io.InputResource;
+
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
+
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
-import org.apache.oro.io.AwkFilenameFilter;
-import org.hibernate.cfg.Configuration;
-import org.wamblee.io.ClassPathResource;
-import org.wamblee.io.InputResource;
-
/**
* Hibernate utilities.
- *
+ *
* @author Erik Brakkee
*/
public final class HibernateUtils {
-
private static final String DATABASE_PROPS = "test.database.properties";
/**
* Disabled.
- *
+ *
*/
- private HibernateUtils() {
+ private HibernateUtils() {
// Empty
}
-
+
/**
+ *
* @param aDir
+ *
* @return
+ *
*/
public static Configuration getConfiguration(File aDir) throws IOException {
Configuration conf = new Configuration();
File[] files = aDir.listFiles((FileFilter) (new AwkFilenameFilter(
- ".*\\.hbm\\.xml")));
+ ".*\\.hbm\\.xml")));
+
for (File f : files) {
System.out.println("Mapping file: " + f);
conf.addFile(f);
Map<String, String> dbProps = getHibernateProperties();
for (Map.Entry<String, String> entry : dbProps.entrySet()) {
- System.out.println("Property: " + entry.getKey() + "="
- + entry.getValue());
+ System.out.println("Property: " + entry.getKey() + "=" +
+ entry.getValue());
conf.setProperty(entry.getKey(), entry.getValue());
}
}
private static Map<String, String> getHibernateProperties()
- throws IOException {
-
+ throws IOException {
System.out.println("Reading properties file: " + DATABASE_PROPS);
+
InputResource lPropFile = new ClassPathResource(DATABASE_PROPS);
Properties props = new Properties();
props.load(lPropFile.getInputStream());
Map<String, String> result = new TreeMap<String, String>();
result.put("hibernate.connection.driver_class", props
- .getProperty("database.driver"));
+ .getProperty("database.driver"));
result.put("hibernate.connection.url", props
- .getProperty("database.url"));
+ .getProperty("database.url"));
result.put("hibernate.connection.username", props
- .getProperty("database.username"));
+ .getProperty("database.username"));
result.put("hibernate.connection.password", props
- .getProperty("database.password"));
+ .getProperty("database.password"));
return result;
}
-
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.test.spring;
import org.springframework.beans.BeansException;
+
import org.springframework.context.ApplicationContext;
+
import org.wamblee.general.BeanFactory;
import org.wamblee.general.BeanFactoryException;
/**
- * Bean factory which uses Spring.
- *
+ * Bean factory which uses Spring.
+ *
* @author Erik Brakkee
*/
public class TestSpringBeanFactory implements BeanFactory {
-
- private ApplicationContext _context;
-
+ private ApplicationContext context;
+
+ /**
+ * Creates a new TestSpringBeanFactory object.
+ *
+ */
public TestSpringBeanFactory(ApplicationContext aContext) {
- _context = aContext;
+ context = aContext;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.general.BeanFactory#find(java.lang.String)
*/
public Object find(String aId) {
- return find(aId, Object.class);
+ return find(aId, Object.class);
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.wamblee.general.BeanFactory#find(java.lang.Class)
*/
public <T> T find(Class<T> aClass) {
return find(aClass.getName(), aClass);
}
- /* (non-Javadoc)
- * @see org.wamblee.general.BeanFactory#find(java.lang.String, java.lang.Class)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.general.BeanFactory#find(java.lang.String,
+ * java.lang.Class)
*/
public <T> T find(String aId, Class<T> aClass) {
try {
- Object obj = _context.getBean(aId, aClass);
- assert obj != null;
- return aClass.cast(obj);
- } catch (BeansException e) {
+ Object obj = context.getBean(aId, aClass);
+ assert obj != null;
+
+ return aClass.cast(obj);
+ } catch (BeansException e) {
throw new BeanFactoryException(e.getMessage(), e);
}
}
-
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Transaction callback for testing. The test will fail if any type of exception
* is thrown.
- *
+ *
* @author Erik Brakkee
*/
public interface TestTransactionCallback {
*
* @return A map containg the resuls of the execution. This is a convenient
* method of returning multiple results from a call.
+ *
*/
Map execute() throws Exception;
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Transaction callback for testing. The test will fail if any type of exception
* is thrown.
- *
+ *
* @author Erik Brakkee
*/
public interface TestTransactionCallbackWithoutResult {
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import org.wamblee.system.core.AbstractComponent;
/**
* A Class Adapter adapts a given class to a Component.
- *
+ *
* @author Erik Brakkee
*/
public class ClassAdapter extends AbstractComponent<Object> {
+ private ClassConfiguration classConfig;
+
+ /**
+ * Creates a new ClassAdapter object.
+ *
+ */
+ public ClassAdapter(String aName, ClassConfiguration aClassConfig) {
+ super(aName, aClassConfig.getProvidedInterfaces().toArray(
+ new ProvidedInterface[0]), aClassConfig.getRequiredInterfaces()
+ .toArray(new RequiredInterface[0]));
+ classConfig = aClassConfig;
+ }
+
+ @Override
+ protected Object doStart(Scope aScope) {
+ Object obj = classConfig.create(aScope);
+ classConfig.inject(aScope, obj);
+
+ for (ProvidedInterface provided : getProvidedInterfaces()) {
+ addInterface(provided, obj, aScope);
+ }
- private ClassConfiguration _classConfig;
+ return obj;
+ }
- public ClassAdapter(String aName, ClassConfiguration aClassConfig) {
- super(aName,
- aClassConfig.getProvidedInterfaces().toArray(new ProvidedInterface[0]),
- aClassConfig.getRequiredInterfaces().toArray(new RequiredInterface[0]));
- _classConfig = aClassConfig;
- }
-
- @Override
- protected Object doStart(Scope aScope) {
-
- Object obj = _classConfig.create(aScope);
- _classConfig.inject(aScope, obj);
-
- for (ProvidedInterface provided: getProvidedInterfaces()) {
- addInterface(provided, obj, aScope);
- }
-
- return obj;
- }
-
- @Override
- protected void doStop(Object aRuntime) {
- // Empty.
- }
+ @Override
+ protected void doStop(Object aRuntime) {
+ // Empty.
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
-import java.util.ArrayList;
-import java.util.List;
-
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * The class configuration encapsulates the knowledge of how to wrap a class as a component.
+ * The class configuration encapsulates the knowledge of how to wrap a class as
+ * a component.
*
* @author Erik Brakkee
- *
*/
public class ClassConfiguration {
+ private Class clazz;
+
+ private ConstructorConfiguration constructorConfig;
+
+ private ObjectConfiguration objectConfig;
+
+ /**
+ * Constructs the configuration. By default no constructor is selected and
+ * one of {@link #select(Class...)} or {@link #greedy()} must be called.
+ *
+ * @param aClass
+ * Class to construct.
+ */
+ public ClassConfiguration(Class aClass) {
+ clazz = aClass;
+ constructorConfig = new ConstructorConfiguration(aClass);
+ objectConfig = new ObjectConfiguration(aClass);
+ }
+
+ public ConstructorConfiguration getConstructorConfig() {
+ return constructorConfig;
+ }
+
+ public ObjectConfiguration getObjectConfig() {
+ return objectConfig;
+ }
+
+ /**
+ * Creates the object in the given scope.
+ *
+ * @param aScope
+ * Scope containing required interfaces for this object.
+ *
+ * @return object.
+ */
+ public Object create(Scope aScope) {
+ return constructorConfig.create(aScope);
+ }
+
+ /**
+ * Injects required interfaces through the setters
+ *
+ * @param aScope
+ * Scope in which injection takes place.
+ * @param aObject
+ * Object to inject into.
+ */
+ public void inject(Scope aScope, Object aObject) {
+ objectConfig.inject(aScope, aObject);
+ }
+
+ public List<ProvidedInterface> getProvidedInterfaces() {
+ List<ProvidedInterface> result = new ArrayList<ProvidedInterface>();
+ result.add(new DefaultProvidedInterface("provided", clazz));
+
+ return result;
+ }
- private Class _class;
- private ConstructorConfiguration _constructorConfig;
- private ObjectConfiguration _objectConfig;
-
- /**
- * Constructs the configuration. By default no constructor is selected and
- * one of {@link #select(Class...)} or
- * {@link #greedy()} must be called.
- * @param aClass Class to construct.
- */
- public ClassConfiguration(Class aClass) {
- _class = aClass;
- _constructorConfig = new ConstructorConfiguration(aClass);
- _objectConfig = new ObjectConfiguration(aClass);
- }
-
- public ConstructorConfiguration getConstructorConfig() {
- return _constructorConfig;
- }
-
- public ObjectConfiguration getObjectConfig() {
- return _objectConfig;
- }
+ public List<RequiredInterface> getRequiredInterfaces() {
+ List<RequiredInterface> result = new ArrayList<RequiredInterface>();
+ result.addAll(constructorConfig.getRequiredInterfaces());
+ result.addAll(objectConfig.getRequiredInterfaces());
- /**
- * Creates the object in the given scope.
- * @param aScope Scope containing required interfaces for this object.
- * @return object.
- */
- public Object create(Scope aScope) {
- return _constructorConfig.create(aScope);
- }
-
- /**
- * Injects required interfaces through the setters
- * @param aObject Object to inject into.
- * @param aScope Scope in which injection takes place.
- */
- public void inject(Scope aScope, Object aObject) {
- _objectConfig.inject(aScope, aObject);
- }
-
- public List<ProvidedInterface> getProvidedInterfaces() {
- List<ProvidedInterface> result = new ArrayList<ProvidedInterface>();
- result.add(new DefaultProvidedInterface("provided", _class));
- return result;
- }
-
- public List<RequiredInterface> getRequiredInterfaces() {
- List<RequiredInterface> result = new ArrayList<RequiredInterface>();
- result.addAll(_constructorConfig.getRequiredInterfaces());
- result.addAll(_objectConfig.getRequiredInterfaces());
- return result;
- }
+ return result;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
import org.wamblee.collections.CollectionFilter;
+
import org.wamblee.conditions.Condition;
+
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
import org.wamblee.system.core.SystemAssemblyException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
- * Class that allows configuration of the constructor to use.
- *
- * In particular, it provides:
+ * Class that allows configuration of the constructor to use. In particular, it
+ * provides:
* <ul>
- * <li> Selection of a constructor using explicit selection
- * {@link #select(Class...)} or using the most greedy constructor
- * {@link #greedy()}.
- * </li>
- * <li>
- * Selection of methods to invoke to inject other objects into the object.
- * </li>
- * <li> Selection of fields to set.
- * </li>
+ * <li>Selection of a constructor using explicit selection
+ * {@link #select(Class...)} or using the most greedy constructor
+ * {@link #greedy()}.</li>
+ * <li>Selection of methods to invoke to inject other objects into the object.</li>
+ * <li>Selection of fields to set.</li>
* </ul>
*/
public class ConstructorConfiguration {
- private Class _class;
- private Constructor<?> _constructor;
- private ParameterValues _values;
- private boolean _publicOnly;
-
- /**
- * Constructs the configuration. By default the public constructor with the
- * most arguments will be used.
- * @param aClass Class to construct.
- */
- public ConstructorConfiguration(Class aClass) {
- _class = aClass;
- _constructor = null;
- _publicOnly = true;
- }
-
- /**
- * Sets whether or no non public constructors are also considered.
- * Reset the choice of a constructor to its default.
- * @param aNonPublic
- * @return
- */
- public ConstructorConfiguration setNonPublic(boolean aNonPublic) {
- _publicOnly = !aNonPublic;
- _constructor = null;
- _values = null;
- return this;
- }
-
- /**
- * Selects an explicit constructor.
- * @param aTypes Arguments of the constructor.
- * @return Return the injector to allow call chaining.
- */
- public ConstructorConfiguration select(Class... aTypes) {
- try {
- _constructor = _class.getDeclaredConstructor(aTypes);
- } catch (Exception e) {
- throw new SystemAssemblyException(e.getMessage(), e);
- }
- resetValues();
- return this;
- }
-
- /**
- * Selects the greediest constructor.
- * @return The injector to allow call chaining.
- * @throws SystemAssemblyException if the greediest constructor cannot be uniquely
- * identified.
- */
- public ConstructorConfiguration greedy() {
- Constructor<?>[] declared = _class.getDeclaredConstructors();
- if (declared.length == 0) {
- throw new SystemAssemblyException("Class '" + _class
- + " is an interface, primitive type, or array");
- }
- int max = -1;
- List<Constructor<?>> checked = new ArrayList<Constructor<?>>();
- CollectionFilter.filter(Arrays.asList(declared), checked,
- new Condition<Constructor<?>>() {
- @Override
- public boolean matches(Constructor<?> aObject) {
- if ( !_publicOnly ) {
- return true;
- } else {
- return Modifier.isPublic(aObject.getModifiers());
- }
- }
- });
- for (Constructor ctor : checked) {
- if (ctor.getParameterTypes().length > max) {
- max = ctor.getParameterTypes().length;
- }
- }
- final int max2 = max;
- List<Constructor<?>> ctors = checked;
- List<Constructor<?>> longest = new ArrayList<Constructor<?>>();
- CollectionFilter.filter(ctors, longest,
- new Condition<Constructor<?>>() {
- @Override
- public boolean matches(Constructor<?> aObject) {
- return aObject.getParameterTypes().length == max2;
- }
- });
- if (longest.size() > 1) {
- throw new SystemAssemblyException(
- "Greediest constructor cannot be uniquely determined");
- }
- _constructor = longest.get(0);
- resetValues();
- return this;
- }
-
- public ParameterValues getParameters() {
- getConstructor(); // initialize constructor if needed.
- return _values;
- }
-
- /**
- * Resets the values.
- */
- private void resetValues() {
- _constructor.setAccessible(true);
- _values = new ParameterValues(_constructor.getParameterTypes());
- }
-
- /**
- * Creates the object in the given scope.
- * @param aScope Scope containing required interfaces for this object.
- * @return object.
- */
- public Object create(Scope aScope) {
- Object[] values = _values.values(aScope);
- try {
- return getConstructor().newInstance(values);
- } catch (Exception e) {
- throw new SystemAssemblyException("Could not construct object "
- + getConstructor() + " " + Arrays.asList(values), e);
- }
- }
-
- public List<RequiredInterface> getRequiredInterfaces() {
- getConstructor(); // initialize constructor if needed.
- return _values.getRequiredInterfaces();
- }
-
- private Constructor getConstructor() {
- if (_constructor == null ) {
- greedy();
- }
- return _constructor;
- }
+ private Class clazz;
+
+ private Constructor<?> constructor;
+
+ private ParameterValues values;
+
+ private boolean publicOnly;
+
+ /**
+ * Constructs the configuration. By default the public constructor with the
+ * most arguments will be used.
+ *
+ * @param aClass
+ * Class to construct.
+ */
+ public ConstructorConfiguration(Class aClass) {
+ clazz = aClass;
+ constructor = null;
+ publicOnly = true;
+ }
+
+ /**
+ * Sets whether or no non public constructors are also considered. Reset the
+ * choice of a constructor to its default.
+ *
+ * @param aNonPublic
+ *
+ * @return
+ */
+ public ConstructorConfiguration setNonPublic(boolean aNonPublic) {
+ publicOnly = !aNonPublic;
+ constructor = null;
+ values = null;
+
+ return this;
+ }
+
+ /**
+ * Selects an explicit constructor.
+ *
+ * @return Return the injector to allow call chaining.
+ *
+ */
+ public ConstructorConfiguration select(Class... aTypes) {
+ try {
+ constructor = clazz.getDeclaredConstructor(aTypes);
+ } catch (Exception e) {
+ throw new SystemAssemblyException(e.getMessage(), e);
+ }
+
+ resetValues();
+
+ return this;
+ }
+
+ /**
+ * Selects the greediest constructor.
+ *
+ * @return The injector to allow call chaining.
+ *
+ * @throws SystemAssemblyException
+ * if the greediest constructor cannot be uniquely identified.
+ */
+ public ConstructorConfiguration greedy() {
+ Constructor<?>[] declared = clazz.getDeclaredConstructors();
+
+ if (declared.length == 0) {
+ throw new SystemAssemblyException("Class '" + clazz +
+ " is an interface, primitive type, or array");
+ }
+
+ int max = -1;
+ List<Constructor<?>> checked = new ArrayList<Constructor<?>>();
+ CollectionFilter.filter(Arrays.asList(declared), checked,
+ new Condition<Constructor<?>>() {
+ @Override
+ public boolean matches(Constructor<?> aObject) {
+ if (!publicOnly) {
+ return true;
+ } else {
+ return Modifier.isPublic(aObject.getModifiers());
+ }
+ }
+ });
+
+ for (Constructor ctor : checked) {
+ if (ctor.getParameterTypes().length > max) {
+ max = ctor.getParameterTypes().length;
+ }
+ }
+
+ final int max2 = max;
+ List<Constructor<?>> ctors = checked;
+ List<Constructor<?>> longest = new ArrayList<Constructor<?>>();
+ CollectionFilter.filter(ctors, longest,
+ new Condition<Constructor<?>>() {
+ @Override
+ public boolean matches(Constructor<?> aObject) {
+ return aObject.getParameterTypes().length == max2;
+ }
+ });
+
+ if (longest.size() > 1) {
+ throw new SystemAssemblyException(
+ "Greediest constructor cannot be uniquely determined");
+ }
+
+ constructor = longest.get(0);
+ resetValues();
+
+ return this;
+ }
+
+ public ParameterValues getParameters() {
+ getConstructor(); // initialize constructor if needed.
+
+ return values;
+ }
+
+ /**
+ * Resets the values.
+ */
+ private void resetValues() {
+ constructor.setAccessible(true);
+ values = new ParameterValues(constructor.getParameterTypes());
+ }
+
+ /**
+ * Creates the object in the given scope.
+ *
+ * @param aScope
+ * Scope containing required interfaces for this object.
+ *
+ * @return object.
+ *
+ */
+ public Object create(Scope aScope) {
+ Object[] valueArray = values.values(aScope);
+
+ try {
+ return getConstructor().newInstance(valueArray);
+ } catch (Exception e) {
+ throw new SystemAssemblyException("Could not construct object " +
+ getConstructor() + " " + Arrays.asList(valueArray), e);
+ }
+ }
+
+ public List<RequiredInterface> getRequiredInterfaces() {
+ getConstructor(); // initialize constructor if needed.
+
+ return values.getRequiredInterfaces();
+ }
+
+ private Constructor getConstructor() {
+ if (constructor == null) {
+ greedy();
+ }
+
+ return constructor;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import org.wamblee.system.container.Container;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultContainer extends Container {
-
+ /**
+ * Creates a new DefaultContainer object.
+ *
+ */
public DefaultContainer(String aName) {
super(aName);
}
@Override
public DefaultContainer addComponent(Component aComponent) {
super.addComponent(aComponent);
+
return this;
}
-
- public DefaultContainer addComponent(String aName, ClassConfiguration aConfiguration) {
+
+ public DefaultContainer addComponent(String aName,
+ ClassConfiguration aConfiguration) {
return addComponent(new ClassAdapter(aName, aConfiguration));
}
- public DefaultContainer addComponent(String aName, Object aObject, ObjectConfiguration aConfiguration) {
- if ( !aConfiguration.appliesTo(aObject) ) {
- throw new IllegalArgumentException("Configuration '" + aConfiguration + "' does nto applu to '" +
- aObject + "'");
+ public DefaultContainer addComponent(String aName, Object aObject,
+ ObjectConfiguration aConfiguration) {
+ if (!aConfiguration.appliesTo(aObject)) {
+ throw new IllegalArgumentException("Configuration '" +
+ aConfiguration + "' does nto applu to '" + aObject + "'");
}
+
return addComponent(new ObjectAdapter(aName, aObject, aConfiguration));
}
-
@Override
public DefaultContainer addRequiredInterface(RequiredInterface aRequired) {
super.addRequiredInterface(aRequired);
+
return this;
}
@Override
public DefaultContainer addProvidedInterface(ProvidedInterface aProvided) {
super.addProvidedInterface(aProvided);
+
return this;
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Value provider that provides a fixed value.
- *
+ *
* @author Erik Brakkee
*/
class FixedValueProvider implements ValueProvider {
-
- private Object _value;
-
- /**
- * Constructs the value.
- * @param aValue Value to construct.
- */
- public FixedValueProvider(Object aValue) {
- _value = aValue;
- }
+ private Object value;
+
+ /**
+ * Constructs the value.
+ *
+ * @param aValue
+ * Value to construct.
+ */
+ public FixedValueProvider(Object aValue) {
+ value = aValue;
+ }
- @Override
- public Object getValue(Scope aScope) {
- return _value;
- }
+ @Override
+ public Object getValue(Scope aScope) {
+ return value;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.Scope;
/**
- * An adapter class that adapts an existing object to a component.
- *
+ * An adapter class that adapts an existing object to a component.
+ *
* @author Erik Brakkee
*/
public class ObjectAdapter extends AbstractComponent<Object> {
+ private ObjectConfiguration objectConfig;
+
+ private Object object;
+
+ /**
+ * Creates a new ObjectAdapter object.
+ *
+ */
+ public ObjectAdapter(String aName, Object aObject,
+ ObjectConfiguration aObjectConfig) {
+ super(aName, new ProvidedInterface[] { new DefaultProvidedInterface(
+ aName, aObject.getClass()) }, aObjectConfig.getRequiredInterfaces()
+ .toArray(new RequiredInterface[0]));
+ objectConfig = aObjectConfig;
+ object = aObject;
+ }
+
+ @Override
+ protected Object doStart(Scope aScope) {
+ objectConfig.inject(aScope, object);
+
+ for (ProvidedInterface provided : getProvidedInterfaces()) {
+ addInterface(provided, object, aScope);
+ }
+
+ return object;
+ }
- private ObjectConfiguration _objectConfig;
- private Object _object;
-
- public ObjectAdapter(String aName, Object aObject, ObjectConfiguration aObjectConfig) {
- super(aName,
- new ProvidedInterface[] { new DefaultProvidedInterface(aName, aObject.getClass()) },
- aObjectConfig.getRequiredInterfaces().toArray(new RequiredInterface[0]));
- _objectConfig = aObjectConfig;
- _object = aObject;
- }
-
- @Override
- protected Object doStart(Scope aScope) {
-
- _objectConfig.inject(aScope, _object);
-
- for (ProvidedInterface provided: getProvidedInterfaces()) {
- addInterface(provided, _object, aScope);
- }
-
- return _object;
- }
-
- @Override
- protected void doStop(Object aRuntime) {
- // Empty.
- }
+ @Override
+ protected void doStop(Object aRuntime) {
+ // Empty.
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
-import java.util.ArrayList;
-import java.util.List;
-
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * General configuration for an instantiated object.
+ * General configuration for an instantiated object.
*
* @author Erik Brakkee
*/
public class ObjectConfiguration {
-
- private Class _class;
- private SetterConfiguration _setterConfig;
+ private Class clazz;
+
+ private SetterConfiguration setterConfig;
- public ObjectConfiguration(Class aClass) {
- _class = aClass;
- _setterConfig = new SetterConfiguration(aClass);
+ /**
+ * Creates a new ObjectConfiguration object.
+ *
+ */
+ public ObjectConfiguration(Class aClass) {
+ clazz = aClass;
+ setterConfig = new SetterConfiguration(aClass);
}
-
+
/**
- * Performs injection into an object of the configured class
- * using information from the given scope.
- * @param aScope Scope.
- * @param aObject Object.
+ * Performs injection into an object of the configured class using
+ * information from the given scope.
+ *
+ * @param aScope
+ * Scope.
+ * @param aObject
+ * Object.
*/
- public void inject(Scope aScope, Object aObject) {
- _setterConfig.inject(aScope, aObject);
+ public void inject(Scope aScope, Object aObject) {
+ setterConfig.inject(aScope, aObject);
}
-
- public SetterConfiguration getSetterConfig() {
- return _setterConfig;
+
+ public SetterConfiguration getSetterConfig() {
+ return setterConfig;
}
-
+
public List<RequiredInterface> getRequiredInterfaces() {
List<RequiredInterface> result = new ArrayList<RequiredInterface>();
- result.addAll(_setterConfig.getRequiredInterfaces());
- return result;
+ result.addAll(setterConfig.getRequiredInterfaces());
+
+ return result;
}
public boolean appliesTo(Object aObject) {
- return _class.isInstance(aObject);
+ return clazz.isInstance(aObject);
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
-import java.util.ArrayList;
-import java.util.List;
-
import org.wamblee.system.core.DefaultRequiredInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
- * Represents parameter values for a method or constructor and allows for the configuration
- * of how these values are retrieved.
+ * Represents parameter values for a method or constructor and allows for the
+ * configuration of how these values are retrieved.
*
* @author Erik Brakkee
*/
public class ParameterValues {
- private String[] _names;
- private Class[] _types;
- private ValueProvider[] _values;
-
- /**
- * Constructs the configuration. By default no constructor is selected and
- * one of {@link #select(Class...)} or
- * {@link #greedy()} must be called.
- * @param aClass Class to construct.
- */
- public ParameterValues(Class[] aTypes) {
- _names = new String[aTypes.length];
- for (int i = 0; i < aTypes.length; i++) {
- _names[i] = "arg" + i;
- }
- _types = aTypes;
- resetValues();
- }
-
- /**
- * Constructs the configuration. By default no constructor is selected and
- * one of {@link #select(Class...)} or
- * {@link #greedy()} must be called.
- * @param aNames Names of the arguments.
- * @param aClass Class to construct.
+ private String[] names;
+
+ private Class[] types;
+
+ private ValueProvider[] values;
+
+ /**
+ * Constructs the configuration. By default no constructor is selected and
+ * one of {@link #select(Class...)} or {@link #greedy()} must be called.
+ *
+ * @param aClass
+ * Class to construct.
+ */
+ public ParameterValues(Class[] aTypes) {
+ names = new String[aTypes.length];
+
+ for (int i = 0; i < aTypes.length; i++) {
+ names[i] = "arg" + i;
+ }
+
+ types = aTypes;
+ resetValues();
+ }
+
+ /**
+ * Constructs the configuration. By default no constructor is selected and
+ * one of {@link #select(Class...)} or {@link #greedy()} must be called.
+ *
+ * @param aNames
+ * Names of the arguments.
+ * @param aClass
+ * Class to construct.
*/
public ParameterValues(String[] aNames, Class[] aTypes) {
- assert aNames.length == aTypes.length;
- _names = aNames;
- _types = aTypes;
- resetValues();
+ assert aNames.length == aTypes.length;
+ names = aNames;
+ types = Arrays.copyOf(aTypes, aTypes.length);
+ resetValues();
+ }
+
+ /**
+ * The types of the parameter values.
+ *
+ * @return Types.
+ */
+ public Class[] getTypes() {
+ return Arrays.copyOf(types, types.length);
+ }
+
+ /**
+ * Sets argument i to be optional, meaning that null is allowed to be passed
+ * in.
+ *
+ * @param aArg
+ * Argument to set.
+ *
+ */
+ public ParameterValues setOptional(int aArg) {
+ values[aArg] = new RequiredInterfaceProvider(
+ new DefaultRequiredInterface("arg" + aArg, types[aArg], true));
+
+ return this;
+ }
+
+ /**
+ * Sets the argument i to a fixed value.
+ *
+ * @param aArg
+ * Argument to set.
+ * @param aValue
+ * Value.
+ *
+ */
+ public ParameterValues setValue(int aArg, Object aValue) {
+ values[aArg] = new FixedValueProvider(aValue);
+
+ return this;
+ }
+
+ /**
+ * Resets the values.
+ */
+ private void resetValues() {
+ values = new ValueProvider[types.length];
+
+ for (int i = 0; i < values.length; i++) {
+ values[i] = new RequiredInterfaceProvider(
+ new DefaultRequiredInterface(names[i], types[i]));
+ }
+ }
+
+ /**
+ * Gets the required interfaces to provide values that are not provided in
+ * another way.
+ *
+ * @return Required interfaces.
+ */
+ public List<RequiredInterface> getRequiredInterfaces() {
+ List<RequiredInterface> result = new ArrayList<RequiredInterface>();
+
+ for (ValueProvider provider : values) {
+ if (provider instanceof RequiredInterfaceProvider) {
+ result.add(((RequiredInterfaceProvider) provider)
+ .getRequiredInterface());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the values to use in the given scope.
+ *
+ * @param aScope
+ * Scope within which to retrieve the values.
+ *
+ * @return Values.
+ */
+ public Object[] values(Scope aScope) {
+ Object[] valueArray = new Object[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ valueArray[i] = values[i].getValue(aScope);
+ }
+
+ return valueArray;
}
-
- /**
- * The types of the parameter values.
- * @return Types.
- */
- public Class[] getTypes() {
- return _types;
- }
-
- /**
- * Sets argument i to be optional, meaning that null is allowed to be passed in.
- * @param aArg Argument to set.
- */
- public ParameterValues setOptional(int aArg) {
- _values[aArg] = new RequiredInterfaceProvider(new DefaultRequiredInterface(
- "arg" + aArg, _types[aArg], true));
- return this;
- }
-
- /**
- * Sets the argument i to a fixed value.
- * @param aArg Argument to set.
- * @param aValue Value.
- */
- public ParameterValues setValue(int aArg, Object aValue) {
- _values[aArg] = new FixedValueProvider(aValue);
- return this;
- }
-
- /**
- * Resets the values.
- */
- private void resetValues() {
- _values = new ValueProvider[_types.length];
- for (int i = 0; i < _values.length; i++) {
- _values[i] = new RequiredInterfaceProvider(new DefaultRequiredInterface(
- _names[i], _types[i]));
- }
- }
-
- /**
- * Gets the required interfaces to provide values that are not provided
- * in another way.
- * @return Required interfaces.
- */
- public List<RequiredInterface> getRequiredInterfaces() {
- List<RequiredInterface> result = new ArrayList<RequiredInterface>();
- for (ValueProvider provider: _values) {
- if ( provider instanceof RequiredInterfaceProvider) {
- result.add( ((RequiredInterfaceProvider)provider).getRequiredInterface());
- }
- }
- return result;
- }
-
- /**
- * Returns the values to use in the given scope.
- * @param aScope Scope within which to retrieve the values.
- * @return Values.
- */
- public Object[] values(Scope aScope) {
- Object[] values = new Object[_values.length];
- for (int i = 0; i < _values.length; i++) {
- values[i] = _values[i].getValue(aScope);
- }
- return values;
- }
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Value provider that provides a value through a required interface.
- *
+ *
* @author Erik Brakkee
*/
class RequiredInterfaceProvider implements ValueProvider {
-
- private RequiredInterface _required;
-
- /**
- * Constructs the provider
- * @param aRequired Required interface.
- */
- public RequiredInterfaceProvider(RequiredInterface aRequired) {
- _required = aRequired;
- }
-
- @Override
- public Object getValue(Scope aScope) {
- return aScope.getInterfaceImplementation(_required.getProvider(), Object.class);
- }
-
- public RequiredInterface getRequiredInterface() {
- return _required;
- }
+ private RequiredInterface required;
+
+ /**
+ * Constructs the provider
+ *
+ * @param aRequired
+ * Required interface.
+ */
+ public RequiredInterfaceProvider(RequiredInterface aRequired) {
+ required = aRequired;
+ }
+
+ @Override
+ public Object getValue(Scope aScope) {
+ return aScope.getInterfaceImplementation(required.getProvider(),
+ Object.class);
+ }
+ public RequiredInterface getRequiredInterface() {
+ return required;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
-import java.awt.CompositeContext;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.wamblee.collections.CollectionFilter;
+
import org.wamblee.conditions.Condition;
import org.wamblee.conditions.FixedCondition;
+
import org.wamblee.general.Pair;
+
import org.wamblee.reflection.ReflectionUtils;
+
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.DefaultRequiredInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.Scope;
import org.wamblee.system.core.SystemAssemblyException;
+import java.awt.CompositeContext;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* Represents the configuration for exposing the setters of a class as required
* interfaces.
* @author Erik Brakkee
*/
public class SetterConfiguration {
+ private Class clazz;
+
+ private boolean publicOnly;
+
+ private Map<Method, ParameterValues> setters;
+
+ /**
+ * Constructs the setter configuration. By default no setters are added.
+ *
+ * @param aClass
+ * Class which is being configured.
+ */
+ public SetterConfiguration(Class aClass) {
+ clazz = aClass;
+ publicOnly = true;
+ setters = new HashMap<Method, ParameterValues>();
+ }
+
+ /**
+ * Makes sure that all available setters are used.
+ *
+ */
+ public SetterConfiguration initAllSetters() {
+ setters.clear();
+
+ for (Method method : getAllSetters(clazz, publicOnly)) {
+ setters.put(method, createParameterValues(method));
+ }
+
+ return this;
+ }
+
+ /**
+ * Called to set whether non-public setters are also used. By default only
+ * public setters are used. The currently selected setters remain chosen.
+ *
+ * @param aIsNonPublic
+ * Non public flag.
+ *
+ */
+ public SetterConfiguration setNonPublic(boolean aIsNonPublic) {
+ publicOnly = !aIsNonPublic;
+
+ return this;
+ }
+
+ /**
+ * Removes all setters.
+ *
+ * @return Reference to the current object to allow call chaining.
+ */
+ public SetterConfiguration clear() {
+ setters.clear();
+
+ return this;
+ }
+
+ /**
+ * Removes a setter from the set of methods.
+ *
+ * @param aName
+ * Name of the setter to remove.
+ *
+ * @return Reference to the current object to allow call chaining.
+ *
+ */
+ public SetterConfiguration remove(String aName) {
+ for (Method method : setters.keySet()) {
+ if (method.getName().equals(aName)) {
+ setters.remove(method);
- private Class _class;
- private boolean _publicOnly;
-
- private Map<Method, ParameterValues> _setters;
-
- /**
- * Constructs the setter configuration. By default no setters are added.
- *
- * @param aClass
- * Class which is being configured.
- */
- public SetterConfiguration(Class aClass) {
- _class = aClass;
- _publicOnly = true;
- _setters = new HashMap<Method, ParameterValues>();
- }
-
- /**
- * Makes sure that all available setters are used.
- */
- public SetterConfiguration initAllSetters() {
- _setters.clear();
- for (Method method: getAllSetters(_class, _publicOnly) ) {
- _setters.put(method, createParameterValues(method));
- }
- return this;
- }
-
- /**
- * Called to set whether non-public setters are also used. By default only
- * public setters are used. The currently selected setters remain chosen.
- *
- * @param aIsNonPublic
- * Non public flag.
- */
- public SetterConfiguration setNonPublic(boolean aIsNonPublic) {
- _publicOnly = !aIsNonPublic;
- return this;
- }
-
- /**
- * Removes all setters.
- *
- * @return Reference to the current object to allow call chaining.
- */
- public SetterConfiguration clear() {
- _setters.clear();
- return this;
- }
-
- /**
- * Removes a setter from the set of methods.
- *
- * @param aName
- * Name of the setter to remove.
- * @return Reference to the current object to allow call chaining.
- */
- public SetterConfiguration remove(String aName) {
- for (Method method : _setters.keySet()) {
- if (method.getName().equals(aName)) {
- _setters.remove(method);
- return this;
- }
- }
- throw new IllegalArgumentException(
- "No method configured by the name of '" + aName + "'");
- }
-
- /**
- * Removes the method from the set of methods.
- * @param aMethod Method to remove.
- * @return
- */
- public SetterConfiguration remove(Method aMethod) {
- if ( !aMethod.getDeclaringClass().isAssignableFrom(_class) ) {
- throw new RuntimeException("Method " + aMethod + " not found in class " + _class + " or its superclasses");
- }
- for (Method method : _setters.keySet()) {
- if (method.equals(aMethod)) {
- _setters.remove(method);
return this;
}
}
+
throw new IllegalArgumentException(
- "Method '" + aMethod + "' was not configured. ");
- }
-
- /**
- * Adds a given setter name to the setters.
- *
- * @param aName Name of a setter method.
- * @return Reference to the current object to allow call chaining.
- */
- public SetterConfiguration add(final String aName) {
- int oldlen = _setters.size();
- List<Method> methods = new ArrayList<Method>();
- CollectionFilter.filter(getAllSetters(_class, _publicOnly), methods,
- new Condition<Method>() {
- @Override
- public boolean matches(Method aObject) {
- return aObject.getName().equals(aName);
- }
-
- });
- if (methods.size() == 0 ) {
- throw new IllegalArgumentException("Method '" + aName
- + "' not found in " + _class.getName());
- }
- // TODO is it possible to get more than one setter here in case the subclass overrides
- // the baseclass method?
- _setters.put(methods.get(0), createParameterValues(methods.get(0)));
- return this;
- }
-
- /**
- * Adds a given setter identified by the type it accepts to the list of
- * setters.N
- *
- * @param aType
- * Type to look for. Note that this must be the exact type as
- * autoboxing and autounboxing is not used.
- * @return Reference to the current object to allow call chaining.
- * @throws IllegalArgumentException
- * In case no setter is found or multiple setters are found.
- */
- public SetterConfiguration addSetter(final Class aType) {
- List<Method> result = new ArrayList<Method>();
- CollectionFilter.filter(getAllSetters(_class, _publicOnly), result,
- new Condition<Method>() {
- @Override
- public boolean matches(Method aObject) {
- Class type = aObject.getParameterTypes()[0];
- return type.equals(aType);
- }
-
- });
- if (result.size() == 0) {
- throw new IllegalArgumentException("No setter found in class '"
- + _class.getName()
- + "' that has a setter with argument type '"
- + aType.getName() + "'");
- }
- if (result.size() > 1) {
- String setters = "";
- for (Method method : result) {
- setters += method.getName() + " ";
- }
- throw new IllegalArgumentException(
- "Multiple setters found in class '" + _class.getName()
- + " that accept type '" + aType.getName() + "': "
- + setters);
- }
- Method method = result.get(0);
- _setters.put(method, createParameterValues(method));
- return this;
- }
-
- /**
- * Gets all setters for the current class.
- *
- * @return List of all setters.
- */
- public static List<Method> getAllSetters(Class aClass,
- boolean aPublicOnly) {
- List<Method> result = new ArrayList<Method>();
- for (Method method : getAllMethods(aClass)) {
- if (!aPublicOnly || Modifier.isPublic(method.getModifiers())) {
- if (method.getName().startsWith("set")
- && method.getParameterTypes().length == 1) {
- method.setAccessible(true);
- result.add(method);
- }
- }
- }
- return result;
- }
-
- private static ParameterValues createParameterValues(Method aMethod) {
-
- Class[] paramTypes = aMethod.getParameterTypes();
- String[] paramNames = new String[paramTypes.length];
- for (int i = 0; i < paramTypes.length; i++) {
- paramNames[i] = aMethod.getName() + "." + i;
- }
- return new ParameterValues(paramNames, paramTypes);
- }
-
- private static final List<Method> getAllMethods(Class aClass) {
- return ReflectionUtils.getAllMethods(aClass);
- }
-
- /**
- * Gets the required interfaces based on the configured setteres.
- *
- * @return List of required interfaces.
- */
- public List<RequiredInterface> getRequiredInterfaces() {
- List<RequiredInterface> result = new ArrayList<RequiredInterface>();
- for (Method method : _setters.keySet()) {
- result.addAll(_setters.get(method).getRequiredInterfaces());
- }
- return result;
- }
-
- /**
- * Invokes all configured setters with the appropriate values.
- *
- * @param aScope
- * Scope within which invocation takes place.
- * @param aObject
- * Object on which the invocation takes place.
- */
- public void inject(Scope aScope, Object aObject) {
- if (!_class.isInstance(aObject)) {
- throw new IllegalArgumentException("Object '" + aObject
- + "' is not an instance of " + _class.getName());
- }
- for (Method method : _setters.keySet()) {
- ParameterValues values = _setters.get(method);
-
- try {
- method.invoke(aObject, values.values(aScope));
- } catch (IllegalAccessException e) {
- throw new SystemAssemblyException("Problem invoking " + method
- + " with " + values, e);
- } catch (InvocationTargetException e) {
- throw new SystemAssemblyException("Problem invoking " + method
- + " with " + values, e);
- }
- }
- }
-
- /**
- * Returns the parameter values for allowing detailed configuration of how
- * parameter values are set.
- *
- * @param aSetter
- * Setter name without the "set" prefix with the first character
- * converted to lower case.
- * @return Parameter values.
- */
- public ParameterValues values(String aMethod) {
- for (Method method : _setters.keySet()) {
- if (method.getName().equals(aMethod)) {
- return _setters.get(method);
- }
- }
- throw new IllegalArgumentException("No setter method '" + aMethod
- + "' found");
- }
-
- public List<Method> getSetters() {
- return new ArrayList<Method>(_setters.keySet());
- }
+ "No method configured by the name of '" + aName + "'");
+ }
+
+ /**
+ * Removes the method from the set of methods.
+ *
+ * @param aMethod
+ * Method to remove.
+ *
+ * @return
+ *
+ */
+ public SetterConfiguration remove(Method aMethod) {
+ if (!aMethod.getDeclaringClass().isAssignableFrom(clazz)) {
+ throw new RuntimeException("Method " + aMethod +
+ " not found in class " + clazz + " or its superclasses");
+ }
+
+ for (Method method : setters.keySet()) {
+ if (method.equals(aMethod)) {
+ setters.remove(method);
+
+ return this;
+ }
+ }
+
+ throw new IllegalArgumentException("Method '" + aMethod +
+ "' was not configured. ");
+ }
+
+ /**
+ * Adds a given setter name to the setters.
+ *
+ * @param aName
+ * Name of a setter method.
+ *
+ * @return Reference to the current object to allow call chaining.
+ *
+ */
+ public SetterConfiguration add(final String aName) {
+ List<Method> methods = new ArrayList<Method>();
+ CollectionFilter.filter(getAllSetters(clazz, publicOnly), methods,
+ new Condition<Method>() {
+ @Override
+ public boolean matches(Method aObject) {
+ return aObject.getName().equals(aName);
+ }
+ });
+
+ if (methods.size() == 0) {
+ throw new IllegalArgumentException("Method '" + aName +
+ "' not found in " + clazz.getName());
+ }
+
+ // TODO is it possible to get more than one setter here in case the
+ // subclass overrides
+ // the baseclass method?
+ setters.put(methods.get(0), createParameterValues(methods.get(0)));
+
+ return this;
+ }
+
+ /**
+ * Adds a given setter identified by the type it accepts to the list of
+ * setters.N
+ *
+ * @param aType
+ * Type to look for. Note that this must be the exact type as
+ * autoboxing and autounboxing is not used.
+ *
+ * @return Reference to the current object to allow call chaining.
+ *
+ * @throws IllegalArgumentException
+ * In case no setter is found or multiple setters are found.
+ */
+ public SetterConfiguration addSetter(final Class aType) {
+ List<Method> result = new ArrayList<Method>();
+ CollectionFilter.filter(getAllSetters(clazz, publicOnly), result,
+ new Condition<Method>() {
+ @Override
+ public boolean matches(Method aObject) {
+ Class type = aObject.getParameterTypes()[0];
+
+ return type.equals(aType);
+ }
+ });
+
+ if (result.size() == 0) {
+ throw new IllegalArgumentException("No setter found in class '" +
+ clazz.getName() + "' that has a setter with argument type '" +
+ aType.getName() + "'");
+ }
+
+ if (result.size() > 1) {
+ StringBuffer setters = new StringBuffer();
+
+ for (Method method : result) {
+ setters.append((method.getName() + " "));
+ }
+
+ throw new IllegalArgumentException(
+ "Multiple setters found in class '" + clazz.getName() +
+ " that accept type '" + aType.getName() + "': " + setters);
+ }
+
+ Method method = result.get(0);
+ setters.put(method, createParameterValues(method));
+
+ return this;
+ }
+
+ /**
+ * Gets all setters for the current class.
+ *
+ *
+ * @return List of all setters.
+ */
+ public static List<Method> getAllSetters(Class aClass, boolean aPublicOnly) {
+ List<Method> result = new ArrayList<Method>();
+
+ for (Method method : getAllMethods(aClass)) {
+ if (!aPublicOnly || Modifier.isPublic(method.getModifiers())) {
+ if (method.getName().startsWith("set") &&
+ (method.getParameterTypes().length == 1)) {
+ method.setAccessible(true);
+ result.add(method);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private static ParameterValues createParameterValues(Method aMethod) {
+ Class[] paramTypes = aMethod.getParameterTypes();
+ String[] paramNames = new String[paramTypes.length];
+
+ for (int i = 0; i < paramTypes.length; i++) {
+ paramNames[i] = aMethod.getName() + "." + i;
+ }
+
+ return new ParameterValues(paramNames, paramTypes);
+ }
+
+ private static final List<Method> getAllMethods(Class aClass) {
+ return ReflectionUtils.getAllMethods(aClass);
+ }
+
+ /**
+ * Gets the required interfaces based on the configured setteres.
+ *
+ * @return List of required interfaces.
+ */
+ public List<RequiredInterface> getRequiredInterfaces() {
+ List<RequiredInterface> result = new ArrayList<RequiredInterface>();
+
+ for (Method method : setters.keySet()) {
+ result.addAll(setters.get(method).getRequiredInterfaces());
+ }
+
+ return result;
+ }
+
+ /**
+ * Invokes all configured setters with the appropriate values.
+ *
+ * @param aScope
+ * Scope within which invocation takes place.
+ * @param aObject
+ * Object on which the invocation takes place.
+ *
+ */
+ public void inject(Scope aScope, Object aObject) {
+ if (!clazz.isInstance(aObject)) {
+ throw new IllegalArgumentException("Object '" + aObject +
+ "' is not an instance of " + clazz.getName());
+ }
+
+ for (Method method : setters.keySet()) {
+ ParameterValues values = setters.get(method);
+
+ try {
+ method.invoke(aObject, values.values(aScope));
+ } catch (IllegalAccessException e) {
+ throw new SystemAssemblyException("Problem invoking " + method +
+ " with " + values, e);
+ } catch (InvocationTargetException e) {
+ throw new SystemAssemblyException("Problem invoking " + method +
+ " with " + values, e);
+ }
+ }
+ }
+
+ /**
+ * Returns the parameter values for allowing detailed configuration of how
+ * parameter values are set.
+ *
+ * @param aMethod
+ * Setter name without the "set" prefix with the first character
+ * converted to lower case.
+ *
+ * @return Parameter values.
+ *
+ */
+ public ParameterValues values(String aMethod) {
+ for (Method method : setters.keySet()) {
+ if (method.getName().equals(aMethod)) {
+ return setters.get(method);
+ }
+ }
+
+ throw new IllegalArgumentException("No setter method '" + aMethod +
+ "' found");
+ }
+
+ public List<Method> getSetters() {
+ return new ArrayList<Method>(setters.keySet());
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.core.Scope;
/**
- * Interface used to provide values for arguments of methods and constructors.
+ * Interface used to provide values for arguments of methods and constructors.
*
* @author Erik Brakkee
*/
interface ValueProvider {
-
- Object getValue(Scope aScope);
+ Object getValue(Scope aScope);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.components;
public class ORMappingConfig {
}
};
- private boolean _schemaUpdate;
- private DatabaseType _type;
+ private boolean schemaUpdate;
+ private DatabaseType type;
public ORMappingConfig(boolean aSchemaUpdate, DatabaseType aType) {
- _schemaUpdate = aSchemaUpdate;
- _type = aType;
+ schemaUpdate = aSchemaUpdate;
+ type = aType;
}
public boolean isSchemaUpdate() {
- return _schemaUpdate;
+ return schemaUpdate;
}
public DatabaseType getType() {
- return _type;
+ return type;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.components;
-import java.io.IOException;
-import java.util.Properties;
-
import org.wamblee.io.InputResource;
+
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.Scope;
+import java.io.IOException;
+
+import java.util.Properties;
+
/**
- * Property component that reads a property file and provides
- * it to other components through a provided interface.
+ * Property component that reads a property file and provides it to other
+ * components through a provided interface. NOTE: when multiple property
+ * components are used, disambiguation of provided and required interfaces is
+ * needed.
*
- * NOTE: when multiple property components are used, disambiguation
- * of provided and required interfaces is needed.
- *
* @author Erik Brakkee
*/
public class PropertyComponent extends AbstractComponent<Properties> {
-
- private static ProvidedInterface PROPS = new DefaultProvidedInterface("props", Properties.class);
-
- private Properties _props;
-
- public PropertyComponent(String aName, InputResource aResource) throws IOException {
- this(aName, readProps(aResource));
- }
-
- private static Properties readProps(InputResource aResource) throws IOException {
- Properties props = new Properties();
- props.load(aResource.getInputStream());
- return props;
+ private static ProvidedInterface PROPS = new DefaultProvidedInterface(
+ "props", Properties.class);
+
+ private Properties props;
+
+ /**
+ * Creates a new PropertyComponent object.
+ *
+ *
+ */
+ public PropertyComponent(String aName, InputResource aResource)
+ throws IOException {
+ this(aName, readProps(aResource));
}
+ /**
+ * Creates a new PropertyComponent object.
+ *
+ */
public PropertyComponent(String aName, Properties aProps) {
super(aName);
- _props = aProps;
-
+ props = aProps;
+
addProvidedInterface(PROPS);
}
+ private static Properties readProps(InputResource aResource)
+ throws IOException {
+ Properties props = new Properties();
+ props.load(aResource.getInputStream());
+
+ return props;
+ }
+
@Override
protected Properties doStart(Scope aScope) {
- addInterface(PROPS, _props, aScope);
- return _props;
+ addInterface(PROPS, props, aScope);
+
+ return props;
}
@Override
protected void doStop(Properties aRuntime) {
- // Empty
+ // Empty
}
-
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.container;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.wamblee.general.Pair;
+
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.Component;
import org.wamblee.system.core.DefaultScope;
import org.wamblee.system.graph.component.ConnectRequiredExternallyRequiredEdgeFilter;
import org.wamblee.system.graph.component.ConnectRequiredProvidedEdgeFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Container consisting of multiple components.
*
* @author Erik Brakkee
*/
public class Container extends AbstractComponent<Scope> {
-
private static final Log LOG = LogFactory.getLog(Container.class);
- private List<Component> _components;
- private CompositeEdgeFilter _edgeFilter;
- private boolean _sealed;
+ private List<Component> components;
+
+ private CompositeEdgeFilter edgeFilter;
+
+ private boolean sealed;
/**
* Constructs the container
* Required services by the container.
*/
public Container(String aName, Component[] aComponents,
- List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
+ List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
super(aName, aProvided, aRequired);
- _components = new ArrayList<Component>();
+ components = new ArrayList<Component>();
+
+ edgeFilter = new CompositeEdgeFilter();
+ sealed = false;
- _edgeFilter = new CompositeEdgeFilter();
- _sealed = false;
for (Component component : aComponents) {
addComponent(component);
}
}
-
+
/**
* Constructs the container
*
* Required services by the container.
*/
public Container(String aName, Component[] aComponents,
- ProvidedInterface[] aProvided, RequiredInterface[] aRequired) {
- this(aName, aComponents, Arrays.asList(aProvided), Arrays.asList(aRequired));
+ ProvidedInterface[] aProvided, RequiredInterface[] aRequired) {
+ this(aName, aComponents, Arrays.asList(aProvided), Arrays
+ .asList(aRequired));
}
+ /**
+ * Creates a new Container object.
+ *
+ */
public Container(String aName) {
this(aName, new Component[0], new ProvidedInterface[0],
- new RequiredInterface[0]);
+ new RequiredInterface[0]);
}
public Container addComponent(Component aComponent) {
checkSealed();
+
if (aComponent.getContext() != null) {
throw new SystemAssemblyException(
- "Inconsistent hierarchy, component '"
- + aComponent.getName()
- + "' is already part of another hierarchy");
+ "Inconsistent hierarchy, component '" + aComponent.getName() +
+ "' is already part of another hierarchy");
}
- if ( findComponent(aComponent.getName()) != null ) {
- throw new SystemAssemblyException("Duplicate component '"
- + aComponent.getName() + "'");
+
+ if (findComponent(aComponent.getName()) != null) {
+ throw new SystemAssemblyException("Duplicate component '" +
+ aComponent.getName() + "'");
}
- _components.add(aComponent);
+
+ components.add(aComponent);
aComponent.addContext(getQualifiedName());
+
return this;
}
-
+
/**
- * Explictly connects required and provided interfaces.
- * @param aClientComponent Client component, may not be null.
- * @param aRequiredInterface Required interface. If null it means all required interfaces.
- * @param aServerComponent Server component to connect to. If null, it means that no server components
- * may be connected to and the provider of the required interface will be null.
- * @param aProvidedInterface Provided interface. If null, it means that there is no restriction on the
- * name of the provided interface and that it is automatically selected.
+ * Explictly connects required and provided interfaces.
+ *
+ * @param aClientComponent
+ * Client component, may not be null.
+ * @param aRequiredInterface
+ * Required interface. If null it means all required interfaces.
+ * @param aServerComponent
+ * Server component to connect to. If null, it means that no
+ * server components may be connected to and the provider of the
+ * required interface will be null.
+ * @param aProvidedInterface
+ * Provided interface. If null, it means that there is no
+ * restriction on the name of the provided interface and that it
+ * is automatically selected.
+ *
*/
- public void connectRequiredProvided(String aClientComponent, String aRequiredInterface,
- String aServerComponent, String aProvidedInterface) {
+ public void connectRequiredProvided(String aClientComponent,
+ String aRequiredInterface, String aServerComponent,
+ String aProvidedInterface) {
checkSealed();
+
Component client = findComponent(aClientComponent);
Component server = findComponent(aServerComponent);
- if ( client == null ) {
- throw new SystemAssemblyException(getQualifiedName() + ": No component '" + aClientComponent + "' in the container");
+
+ if (client == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": No component '" + aClientComponent + "' in the container");
}
- if ( aRequiredInterface != null ) {
- if ( findInterface(client.getRequiredInterfaces(), aRequiredInterface) == null ) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aClientComponent + "' does not have a required interface named '"
- + aRequiredInterface + "'");
- }
+
+ if (aRequiredInterface != null) {
+ if (findInterface(client.getRequiredInterfaces(),
+ aRequiredInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aClientComponent +
+ "' does not have a required interface named '" +
+ aRequiredInterface + "'");
+ }
}
- if ( server == null ) {
- throw new SystemAssemblyException("No component '" + aClientComponent + "' in the container");
+
+ if (server == null) {
+ throw new SystemAssemblyException("No component '" +
+ aClientComponent + "' in the container");
}
- if ( aProvidedInterface != null ) {
- if ( findInterface(server.getProvidedInterfaces(), aProvidedInterface) == null) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aServerComponent + "' does not have a provided interface named '"
- + aProvidedInterface + "'");
- }
+
+ if (aProvidedInterface != null) {
+ if (findInterface(server.getProvidedInterfaces(),
+ aProvidedInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aServerComponent +
+ "' does not have a provided interface named '" +
+ aProvidedInterface + "'");
+ }
}
- _edgeFilter.add(new ConnectRequiredProvidedEdgeFilter(aClientComponent, aRequiredInterface, aServerComponent, aProvidedInterface));
+
+ edgeFilter.add(new ConnectRequiredProvidedEdgeFilter(aClientComponent,
+ aRequiredInterface, aServerComponent, aProvidedInterface));
}
-
+
/**
- * Explicitly connects a externally required interface to an internally required interface.
- * @param aComponent Component requiring the interface (must be non-null).
- * @param aRequiredInterface Required interface of the component (must be non-null).
- * @param aExternalRequiredInterface Externally required interface (must be non-null).
+ * Explicitly connects a externally required interface to an internally
+ * required interface.
+ *
+ * @param aComponent
+ * Component requiring the interface (must be non-null).
+ * @param aRequiredInterface
+ * Required interface of the component (must be non-null).
+ * @param aExternalRequiredInterface
+ * Externally required interface (must be non-null).
+ *
*/
- public void connectExternalRequired(String aComponent, String aRequiredInterface,
- String aExternalRequiredInterface) {
+ public void connectExternalRequired(String aComponent,
+ String aRequiredInterface, String aExternalRequiredInterface) {
checkSealed();
+
Component client = findComponent(aComponent);
- if ( client == null ) {
- throw new SystemAssemblyException(getQualifiedName() + ": No component '" + aComponent + "' in the container");
+
+ if (client == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": No component '" + aComponent + "' in the container");
}
- if ( aRequiredInterface != null ) {
- if ( findInterface(client.getRequiredInterfaces(), aRequiredInterface) == null ) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aComponent + "' does not have a required interface named '"
- + aRequiredInterface + "'");
- }
+
+ if (aRequiredInterface != null) {
+ if (findInterface(client.getRequiredInterfaces(),
+ aRequiredInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aComponent +
+ "' does not have a required interface named '" +
+ aRequiredInterface + "'");
+ }
}
- if ( aExternalRequiredInterface != null) {
- if ( findInterface(getRequiredInterfaces(), aExternalRequiredInterface) == null ) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": container does not have a required interface named '"
- + aExternalRequiredInterface + "'");
- }
+
+ if (aExternalRequiredInterface != null) {
+ if (findInterface(getRequiredInterfaces(),
+ aExternalRequiredInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": container does not have a required interface named '" +
+ aExternalRequiredInterface + "'");
+ }
}
- _edgeFilter.add(new ConnectRequiredExternallyRequiredEdgeFilter(
- aComponent, aRequiredInterface, aExternalRequiredInterface));
+
+ edgeFilter.add(new ConnectRequiredExternallyRequiredEdgeFilter(
+ aComponent, aRequiredInterface, aExternalRequiredInterface));
}
-
- public void connectExternalProvided(String aExternalProvided, String aComponent, String aProvidedInterface) {
+
+ public void connectExternalProvided(String aExternalProvided,
+ String aComponent, String aProvidedInterface) {
checkSealed();
+
Component server = findComponent(aComponent);
-
-
- if ( server == null ) {
- throw new SystemAssemblyException("No component '" + aComponent + "' in the container");
+
+ if (server == null) {
+ throw new SystemAssemblyException("No component '" + aComponent +
+ "' in the container");
}
- if ( aProvidedInterface != null ) {
- if ( findInterface(server.getProvidedInterfaces(), aProvidedInterface) == null) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aComponent + "' does not have a provided interface named '"
- + aProvidedInterface + "'");
- }
+
+ if (aProvidedInterface != null) {
+ if (findInterface(server.getProvidedInterfaces(),
+ aProvidedInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aComponent +
+ "' does not have a provided interface named '" +
+ aProvidedInterface + "'");
+ }
}
- if ( aExternalProvided != null ) {
- if ( findInterface(getProvidedInterfaces(), aExternalProvided) == null) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Container does not have a provided interface named '"
- + aExternalProvided + "'");
- }
+
+ if (aExternalProvided != null) {
+ if (findInterface(getProvidedInterfaces(), aExternalProvided) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Container does not have a provided interface named '" +
+ aExternalProvided + "'");
+ }
}
- _edgeFilter.add(new ConnectExternalProvidedProvidedFilter(aExternalProvided, aComponent, aProvidedInterface));
- }
+ edgeFilter.add(new ConnectExternalProvidedProvidedFilter(
+ aExternalProvided, aComponent, aProvidedInterface));
+ }
@Override
public Container addProvidedInterface(ProvidedInterface aProvided) {
checkSealed();
super.addProvidedInterface(aProvided);
+
return this;
}
public Container addRequiredInterface(RequiredInterface aRequired) {
checkSealed();
super.addRequiredInterface(aRequired);
+
return this;
}
@Override
public void addContext(String aContext) {
super.addContext(aContext);
- for (Component component : _components) {
+
+ for (Component component : components) {
component.addContext(aContext);
}
}
* services not in the required list and no services in the provided list
* that cannot be provided. Also logs a warning in case of superfluous
* requirements.
- *
- * @throws SystemAssemblyException
- * in case of any validation problems.
*/
public void validate() {
doStartOptionalDryRun(null, true);
* be added.
*/
public void seal() {
- _sealed = true;
+ sealed = true;
}
/**
* @return True iff the container is sealed.
*/
public boolean isSealed() {
- return _sealed;
+ return sealed;
}
/**
*/
public Scope start() {
Scope scope = new DefaultScope(getProvidedInterfaces());
+
return super.start(scope);
}
@Override
protected Scope doStart(Scope aExternalScope) {
validate();
- Scope scope = new DefaultScope(getProvidedInterfaces().toArray(new ProvidedInterface[0]), aExternalScope);
+
+ Scope scope = new DefaultScope(getProvidedInterfaces().toArray(
+ new ProvidedInterface[0]), aExternalScope);
ComponentGraph graph = doStartOptionalDryRun(scope, false);
exposeProvidedInterfaces(graph, aExternalScope, scope);
seal();
+
return scope;
}
- private void exposeProvidedInterfaces(ComponentGraph aGraph, Scope aExternalScope,
- Scope aInternalScope) {
- for (Pair<ProvidedInterface,ProvidedInterface> mapping:
- aGraph.findExternalProvidedInterfaceMapping()) {
- Object svc = aInternalScope.getInterfaceImplementation(mapping.getSecond(), Object.class);
+ private void exposeProvidedInterfaces(ComponentGraph aGraph,
+ Scope aExternalScope, Scope aInternalScope) {
+ for (Pair<ProvidedInterface, ProvidedInterface> mapping : aGraph
+ .findExternalProvidedInterfaceMapping()) {
+ Object svc = aInternalScope.getInterfaceImplementation(mapping
+ .getSecond(), Object.class);
addInterface(mapping.getFirst(), svc, aExternalScope);
}
}
LOG.info("Starting '" + getQualifiedName() + "'");
List<Component> started = new ArrayList<Component>();
- for (Component component : _components) {
+
+ for (Component component : components) {
try {
// Start the service.
if (!aDryRun) {
} catch (SystemAssemblyException e) {
throw e;
} catch (RuntimeException e) {
- LOG.error(getQualifiedName() + ": could not start '"
- + component.getQualifiedName() + "'", e);
+ LOG.error(getQualifiedName() + ": could not start '" +
+ component.getQualifiedName() + "'", e);
stopAlreadyStartedComponents(started, aScope);
throw e;
}
}
+
return graph;
}
private ComponentGraph createComponentGraph() {
ComponentGraph graph = new ComponentGraph();
+
for (RequiredInterface req : getRequiredInterfaces()) {
graph.addRequiredInterface(this, req);
}
- for (Component comp : _components) {
+
+ for (Component comp : components) {
graph.addComponent(comp);
}
- for (ProvidedInterface prov: getProvidedInterfaces()) {
+
+ for (ProvidedInterface prov : getProvidedInterfaces()) {
graph.addProvidedInterface(this, prov);
}
- graph.addEdgeFilter(_edgeFilter);
+ graph.addEdgeFilter(edgeFilter);
+
return graph;
}
private void stopAlreadyStartedComponents(List<Component> aStarted,
- Scope aScope) {
+ Scope aScope) {
// an exception occurred, stop the successfully started
// components
for (int i = aStarted.size() - 1; i >= 0; i--) {
Component component = aStarted.get(i);
aStarted.get(i).stop(aScope.getRuntime(component));
} catch (Throwable t) {
- LOG.error(getQualifiedName() + ": error stopping "
- + aStarted.get(i).getQualifiedName());
+ LOG.error(getQualifiedName() + ": error stopping " +
+ aStarted.get(i).getQualifiedName());
}
}
}
@Override
protected void doStop(Scope aScope) {
- for (int i = _components.size() - 1; i >= 0; i--) {
- Component component = _components.get(i);
+ for (int i = components.size() - 1; i >= 0; i--) {
+ Component component = components.get(i);
Object runtime = aScope.getRuntime(component);
component.stop(runtime);
}
}
private void checkSealed() {
- if (_sealed) {
+ if (sealed) {
throw new SystemAssemblyException("Container is sealed");
}
}
-
+
/**
- * Finds a component based on the non-qualified name of the component.
- * @param aName Component name.
- * @return Component or null if not found.
+ * Finds a component based on the non-qualified name of the component.
+ *
+ * @param aName
+ * Component name.
+ *
+ * @return Component or null if not found.
*/
- public Component findComponent(String aName) {
- for (Component<?> component: _components) {
- if ( component.getName().equals(aName)) {
- return component;
- }
- }
- return null;
+ public Component findComponent(String aName) {
+ for (Component<?> component : components) {
+ if (component.getName().equals(aName)) {
+ return component;
+ }
+ }
+
+ return null;
}
-
- private static <T extends NamedInterface> T findInterface(List<T> aInterfaces, String aInterfaceName) {
- for (T intf: aInterfaces) {
- if ( intf.getName().equals(aInterfaceName)) {
- return intf;
- }
- }
- return null;
+
+ private static <T extends NamedInterface> T findInterface(
+ List<T> aInterfaces, String aInterfaceName) {
+ for (T intf : aInterfaces) {
+ if (intf.getName().equals(aInterfaceName)) {
+ return intf;
+ }
+ }
+
+ return null;
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
/**
* Abstract subsystem class making it easy to implement new subsystems.
+ *
*/
public abstract class AbstractComponent<Type> implements Component<Type> {
+ private static final Log LOG = LogFactory.getLog(AbstractComponent.class);
+
+ private ThreadLocal<List<ProvidedInterface>> remaining;
+
+ private String context;
+
+ private String name;
+
+ private List<ProvidedInterface> provided;
+
+ private List<RequiredInterface> required;
+
+ /**
+ * Constructs the subsystem.
+ *
+ * @param aName
+ * Name of the system.
+ * @param aProvided
+ * Provided services.
+ * @param aRequired
+ * Required services.
+ */
+ protected AbstractComponent(String aName,
+ List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
+ remaining = new ThreadLocal<List<ProvidedInterface>>();
+ context = null;
+ name = aName;
+ provided = new ArrayList<ProvidedInterface>(aProvided);
+ required = new ArrayList<RequiredInterface>(aRequired);
+ }
- private static final Log LOG = LogFactory.getLog(AbstractComponent.class);
-
- private ThreadLocal<List<ProvidedInterface>> _remaining;
-
- private String _context;
- private String _name;
- private List<ProvidedInterface> _provided;
- private List<RequiredInterface> _required;
-
- /**
- * Constructs the subsystem.
- *
- * @param aName
- * Name of the system.
- * @param aProvided
- * Provided services.
- * @param aRequired
- * Required services.
- */
- protected AbstractComponent(String aName, List<ProvidedInterface> aProvided,
- List<RequiredInterface> aRequired) {
- _remaining = new ThreadLocal<List<ProvidedInterface>>();
- _context = null;
- _name = aName;
- _provided = new ArrayList<ProvidedInterface>(aProvided);
- _required = new ArrayList<RequiredInterface>(aRequired);
- }
-
- /**
+ /**
* Constructs the subsystem.
*
* @param aName
* Required services.
*/
protected AbstractComponent(String aName, ProvidedInterface[] aProvided,
- RequiredInterface[] aRequired) {
+ RequiredInterface[] aRequired) {
this(aName, Arrays.asList(aProvided), Arrays.asList(aRequired));
}
-
- protected AbstractComponent(String aName) {
- this(aName, new ProvidedInterface[0], new RequiredInterface[0]);
- }
-
- public AbstractComponent<Type> addProvidedInterface(ProvidedInterface aProvided) {
- _provided.add(aProvided);
- return this;
- }
-
- public AbstractComponent<Type> addRequiredInterface(RequiredInterface aRequired) {
- _required.add(aRequired);
- return this;
- }
-
- @Override
- public final String getName() {
- return _name;
- }
-
- @Override
- public void addContext(String aContext) {
- if (_context == null) {
- _context = aContext;
- } else {
- _context = aContext + "." + _context;
- }
- }
-
- @Override
- public String getContext() {
- return _context;
- }
-
- @Override
- public String getQualifiedName() {
- if (_context == null) {
- return getName();
- }
- return _context + "." + getName();
- }
-
- @Override
- public final List<ProvidedInterface> getProvidedInterfaces() {
- return Collections.unmodifiableList(_provided);
- }
-
- @Override
- public final List<RequiredInterface> getRequiredInterfaces() {
- return Collections.unmodifiableList(_required);
- }
-
- @Override
- public final Type start(Scope aScope) {
- LOG.info("Initialization starting '" + getQualifiedName() + "'");
- List<ProvidedInterface> oldRemaining = _remaining.get();
- _remaining.set(new ArrayList<ProvidedInterface>(getProvidedInterfaces()));
- try {
- Type runtime = doStart(aScope);
- checkNotStartedInterfaces();
- LOG.info("Initialization finished '" + getQualifiedName() + "'");
- return runtime;
- } finally {
- _remaining.set(oldRemaining);
- }
- }
-
- private void checkNotStartedInterfaces() {
- if (_remaining.get().size() > 0) {
- String notProvided = "";
- for (ProvidedInterface provided : _remaining.get()) {
- notProvided += "\nComponent " + getQualifiedName()
- + " did not start interface " + provided;
- }
- throw new SystemAssemblyException(notProvided);
- }
- }
-
- /**
- * Must be implemented for initializing the subsystem. The implementation
- * must call {@link #addInterface(ProvidedInterface, Object, Scope)} for each service that is started.
- *
- * @return Returns the runtime of the component.
- */
- protected abstract Type doStart(Scope aScope);
-
- /**
- * Implementations must call this method to indicate that a new service has
- * been started.
- *
- * @param aDescriptor
- * Provided interface.
- * @param aService
- * Implementation of the interface.
- * @param aScope
- * scope in which to publish the implementation.
- */
- protected final void addInterface(ProvidedInterface aDescriptor,
- Object aService, Scope aScope) {
- LOG.info("Interface '" + getQualifiedName() + "."
- + aDescriptor.getName() + "' started.");
- if ( !_remaining.get().remove(aDescriptor) ) {
- throw new SystemAssemblyException("Component '" + getQualifiedName() + "' started an unexpected interface '" +
- aDescriptor + "' that was not registerd as a provided interface before");
- }
- aScope.publishInterface(aDescriptor, aService);
- }
-
- @Override
- public void stop(Type aRuntime) {
- LOG.info("Stopping initiated '" + getQualifiedName() + "'");
- doStop(aRuntime);
- LOG.info("Stopping completed '" + getQualifiedName() + "'");
- }
-
- protected abstract void doStop(Type aRuntime);
-
- @Override
- public String toString() {
- return getQualifiedName();
- }
-
- public ProvidedInterface findProvidedInterface(String aName) {
- for (ProvidedInterface provided: getProvidedInterfaces()) {
- if ( provided.getName().equals(aName)) {
- return provided;
- }
- }
- return null;
- }
-
- public RequiredInterface findRequiredInterface(String aName) {
- for (RequiredInterface required: getRequiredInterfaces()) {
- if ( required.getName().equals(aName)) {
- return required;
- }
- }
- return null;
- }
+ /**
+ * Creates a new AbstractComponent object.
+ *
+ */
+ protected AbstractComponent(String aName) {
+ this(aName, new ProvidedInterface[0], new RequiredInterface[0]);
+ }
+
+ public AbstractComponent<Type> addProvidedInterface(
+ ProvidedInterface aProvided) {
+ provided.add(aProvided);
+
+ return this;
+ }
+
+ public AbstractComponent<Type> addRequiredInterface(
+ RequiredInterface aRequired) {
+ required.add(aRequired);
+
+ return this;
+ }
+
+ @Override
+ public final String getName() {
+ return name;
+ }
+
+ @Override
+ public void addContext(String aContext) {
+ if (context == null) {
+ context = aContext;
+ } else {
+ context = aContext + "." + context;
+ }
+ }
+
+ @Override
+ public String getContext() {
+ return context;
+ }
+
+ @Override
+ public String getQualifiedName() {
+ if (context == null) {
+ return getName();
+ }
+
+ return context + "." + getName();
+ }
+
+ @Override
+ public final List<ProvidedInterface> getProvidedInterfaces() {
+ return Collections.unmodifiableList(provided);
+ }
+
+ @Override
+ public final List<RequiredInterface> getRequiredInterfaces() {
+ return Collections.unmodifiableList(required);
+ }
+
+ @Override
+ public final Type start(Scope aScope) {
+ LOG.info("Initialization starting '" + getQualifiedName() + "'");
+
+ List<ProvidedInterface> oldRemaining = remaining.get();
+ remaining
+ .set(new ArrayList<ProvidedInterface>(getProvidedInterfaces()));
+
+ try {
+ Type runtime = doStart(aScope);
+ checkNotStartedInterfaces();
+ LOG.info("Initialization finished '" + getQualifiedName() + "'");
+
+ return runtime;
+ } finally {
+ remaining.set(oldRemaining);
+ }
+ }
+
+ private void checkNotStartedInterfaces() {
+ if (remaining.get().size() > 0) {
+ StringBuffer notProvided = new StringBuffer();
+
+ for (ProvidedInterface provided : remaining.get()) {
+ notProvided.append("\nComponent " + getQualifiedName() +
+ " did not start interface " + provided);
+ }
+
+ throw new SystemAssemblyException(notProvided.toString());
+ }
+ }
+
+ /**
+ * Must be implemented for initializing the subsystem. The implementation
+ * must call {@link #addInterface(ProvidedInterface, Object, Scope)} for
+ * each service that is started.
+ *
+ *
+ * @return Returns the runtime of the component.
+ */
+ protected abstract Type doStart(Scope aScope);
+
+ /**
+ * Implementations must call this method to indicate that a new service has
+ * been started.
+ *
+ * @param aDescriptor
+ * Provided interface.
+ * @param aService
+ * Implementation of the interface.
+ * @param aScope
+ * scope in which to publish the implementation.
+ *
+ */
+ protected final void addInterface(ProvidedInterface aDescriptor,
+ Object aService, Scope aScope) {
+ LOG.info("Interface '" + getQualifiedName() + "." +
+ aDescriptor.getName() + "' started.");
+
+ if (!remaining.get().remove(aDescriptor)) {
+ throw new SystemAssemblyException("Component '" +
+ getQualifiedName() + "' started an unexpected interface '" +
+ aDescriptor +
+ "' that was not registerd as a provided interface before");
+ }
+
+ aScope.publishInterface(aDescriptor, aService);
+ }
+
+ @Override
+ public void stop(Type aRuntime) {
+ LOG.info("Stopping initiated '" + getQualifiedName() + "'");
+ doStop(aRuntime);
+ LOG.info("Stopping completed '" + getQualifiedName() + "'");
+ }
+
+ protected abstract void doStop(Type aRuntime);
+
+ @Override
+ public String toString() {
+ return getQualifiedName();
+ }
+
+ public ProvidedInterface findProvidedInterface(String aName) {
+ for (ProvidedInterface provided : getProvidedInterfaces()) {
+ if (provided.getName().equals(aName)) {
+ return provided;
+ }
+ }
+
+ return null;
+ }
+
+ public RequiredInterface findRequiredInterface(String aName) {
+ for (RequiredInterface required : getRequiredInterfaces()) {
+ if (required.getName().equals(aName)) {
+ return required;
+ }
+ }
+
+ return null;
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.List;
/**
- * A component represents a part of a system that requires a
- * number of interfaces and provides a number of interfaces.
+ * A component represents a part of a system that requires a number of
+ * interfaces and provides a number of interfaces.
+ *
+ * The component interface provides the meta-data for a component. After calling
+ * {@link #start(Scope)}, an actual runtime representation of the component can
+ * be created which is independent of this component. As a special case, the
+ * runtime representation may be identical to the component instance but in
+ * general it is not. This allows a component to be used as a factory for
+ * creating objects.
*
- * The component interface provides the meta-data for a component.
- * After calling {@link #start(Scope)}, an actual runtime representation of the
- * component can be created which is independent of this component.
- * As a special case, the runtime representation may be identical to the
- * component instance but in general it is not. This allows a component to be
- * used as a factory for creating objects.
*
- *
* @author Erik Brakkee
*/
public interface Component<Type> {
-
- /**
- * Gets the name of the subsystem.
- * @return Subsystem name.
- */
- String getName();
-
- /**
- * Prepends the context with a super context.
- */
- void addContext(String aContext);
-
- /**
- * Getst the context.
- * @return Context or null if not set.
- */
- String getContext();
-
- /**
- * Gets the fully qualified name of the component which includes
- * the context of the component.
- * This method can only be used after the component has started.
- * @return Qualified name.
- */
- String getQualifiedName();
+ /**
+ * Gets the name of the subsystem.
+ *
+ * @return Subsystem name.
+ */
+ String getName();
+
+ /**
+ * Prepends the context with a super context.
+ *
+ */
+ void addContext(String aContext);
+
+ /**
+ * Getst the context.
+ *
+ * @return Context or null if not set.
+ */
+ String getContext();
+
+ /**
+ * Gets the fully qualified name of the component which includes the context
+ * of the component. This method can only be used after the component has
+ * started.
+ *
+ * @return Qualified name.
+ */
+ String getQualifiedName();
+
+ /**
+ * Gets a description of the provided interfaces.
+ *
+ * @return Provided interfaces.
+ */
+ List<ProvidedInterface> getProvidedInterfaces();
+
+ /**
+ * Gets a description of the required interfaces.
+ *
+ * @return Required interfaces.
+ */
+ List<RequiredInterface> getRequiredInterfaces();
- /**
- * Gets a description of the provided interfaces.
- * @return Provided interfaces.
- */
- List<ProvidedInterface> getProvidedInterfaces();
-
- /**
- * Gets a description of the required interfaces.
- * @return Required interfaces.
- */
- List<RequiredInterface> getRequiredInterfaces();
+ /**
+ * Initialises the subsystem by starting all the services that it described
+ * as provided.
+ *
+ * @param aScope
+ * Scope with external interface implementations that are
+ * available. The component must publish its runtime and its
+ * provided interfaces in this scope.
+ *
+ * @return Gets an object representing the runtime of the component.
+ */
+ Type start(Scope aScope);
-
- /**
- * Initialises the subsystem by starting all the services that
- * it described as provided.
- * @param aScope Scope with external interface implementations that are available. The component
- * must publish its runtime and its provided interfaces in this scope.
- * @return Gets an object representing the runtime of the component.
- */
- Type start(Scope aScope);
-
- /**
- * Stops a component.
- * @param aRuntime THe runtime part of the component.
- */
- void stop(Type aRuntime);
+ /**
+ * Stops a component.
+ *
+ * @param aRuntime
+ * THe runtime part of the component.
+ */
+ void stop(Type aRuntime);
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.Collections;
import java.util.List;
-
/**
* Default implementation of a service descriptor.
- *
+ *
* @author Erik Brakkee
*/
public class DefaultProvidedInterface implements ProvidedInterface {
-
- private String _name;
- private Class[] _interfaces;
-
- /**
- * Constructs the descriptor.
- * @param aInterface Type of service.
- */
- public DefaultProvidedInterface(String aName, Class aInterface) {
- this(aName, new Class[] { aInterface });
- }
-
- public DefaultProvidedInterface(String aName, Class[] aInterfaces) {
- _name = aName;
- _interfaces = Arrays.copyOf(aInterfaces, aInterfaces.length);
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- public Class[] getInterfaceTypes() {
- return _interfaces;
- }
-
- @Override
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append(getName());
- buf.append(":");
- for (Class intf: _interfaces) {
- buf.append(" " + intf.getName());
- }
- return buf.toString();
- }
-
- @Override
- public boolean equals(Object aObj) {
- return this == aObj;
- /*
- if ( !(aObj instanceof DefaultProvidedInterface)) {
- return false;
- }
- DefaultProvidedInterface provided = (DefaultProvidedInterface)aObj;
- return getEqualsRepresentation().equals(provided.getEqualsRepresentation());
- */
- }
-
- @Override
- public int hashCode() {
- return getEqualsRepresentation().hashCode();
- }
-
- @Override
- public boolean covers(ProvidedInterface aInterface) {
- // TODO do more than just equals.
- if ( !(aInterface instanceof DefaultProvidedInterface)) {
- return false;
- }
- return getEqualsRepresentation().equals(((DefaultProvidedInterface)aInterface).getEqualsRepresentation());
- }
-
-
- private String getEqualsRepresentation() {
- List<String> result = new ArrayList<String>();
- for (Class cls: _interfaces) {
- result.add(cls.getName());
- }
- Collections.sort(result);
- String value = "";
- for (String str: result) {
- value += ":" + str;
- }
- return value;
- }
+ private String name;
+
+ private Class[] interfaces;
+
+ /**
+ * Constructs the descriptor.
+ *
+ * @param aInterface
+ * Type of service.
+ */
+ public DefaultProvidedInterface(String aName, Class aInterface) {
+ this(aName, new Class[] { aInterface });
+ }
+
+ /**
+ * Creates a new DefaultProvidedInterface object.
+ *
+ */
+ public DefaultProvidedInterface(String aName, Class[] aInterfaces) {
+ name = aName;
+ interfaces = Arrays.copyOf(aInterfaces, aInterfaces.length);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Class[] getInterfaceTypes() {
+ return interfaces;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append(getName());
+ buf.append(":");
+
+ for (Class intf : interfaces) {
+ buf.append(" " + intf.getName());
+ }
+
+ return buf.toString();
+ }
+
+ @Override
+ public boolean equals(Object aObj) {
+ return this == aObj;
+
+ /*
+ * if ( !(aObj instanceof DefaultProvidedInterface)) { return false; }
+ * DefaultProvidedInterface provided = (DefaultProvidedInterface)aObj;
+ * return
+ * getEqualsRepresentation().equals(provided.getEqualsRepresentation());
+ */
+ }
+
+ @Override
+ public int hashCode() {
+ return getEqualsRepresentation().hashCode();
+ }
+
+ @Override
+ public boolean covers(ProvidedInterface aInterface) {
+ // TODO do more than just equals.
+ if (!(aInterface instanceof DefaultProvidedInterface)) {
+ return false;
+ }
+
+ return getEqualsRepresentation().equals(
+ ((DefaultProvidedInterface) aInterface).getEqualsRepresentation());
+ }
+
+ private String getEqualsRepresentation() {
+ List<String> result = new ArrayList<String>();
+
+ for (Class cls : interfaces) {
+ result.add(cls.getName());
+ }
+
+ Collections.sort(result);
+
+ StringBuffer value = new StringBuffer();
+
+ for (String str : result) {
+ value.append(":" + str);
+ }
+
+ return value.toString();
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.core;
-import java.util.Arrays;
-
import org.wamblee.reflection.ReflectionUtils;
+import java.util.Arrays;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultRequiredInterface implements RequiredInterface {
+ private String name;
+
+ private boolean optional;
+
+ private Class[] required;
+
+ private ProvidedInterface provider;
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class aInterface) {
+ this(aName, new Class[] { aInterface });
+ }
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class[] aInterfaces) {
+ this(aName, aInterfaces, false);
+ }
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class aInterface,
+ boolean aIsOptional) {
+ this(aName, new Class[] { aInterface }, aIsOptional);
+ }
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class[] aInterfaces,
+ boolean aIsOptional) {
+ name = aName;
+ optional = aIsOptional;
+ required = aInterfaces;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean isOptional() {
+ return optional;
+ }
+
+ @Override
+ public boolean implementedBy(ProvidedInterface aDescriptor) {
+ Class[] provided = aDescriptor.getInterfaceTypes();
+
+ for (Class requiredIntf : required) {
+ if (!serviceProvided(requiredIntf, provided)) {
+ return false;
+ }
+ }
+
+ // all required interfaces are provided.
+ return true;
+ }
+
+ /**
+ * Check if the required interface is implemented by one of the provided
+ * interfaces.
+ *
+ * @param aRequired
+ * required interface
+ * @param aProvided
+ * Provided interfaces.
+ *
+ * @return
+ */
+ private boolean serviceProvided(Class aRequired, Class[] aProvided) {
+ for (Class provided : aProvided) {
+ try {
+ provided = ReflectionUtils.wrapIfNeeded(provided);
+ aRequired = ReflectionUtils.wrapIfNeeded(aRequired);
+ provided.asSubclass(aRequired);
+
+ return true;
+ } catch (ClassCastException e) {
+ // No match, try the next one.
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public ProvidedInterface getProvider() {
+ return provider;
+ }
+
+ @Override
+ public void setProvider(ProvidedInterface aProvider) {
+ assert aProvider != null;
+ assert implementedBy(aProvider);
+ provider = aProvider;
+ }
+
+ @Override
+ public boolean equals(Object aObject) {
+ return this == aObject;
+ }
+
+ @Override
+ public boolean covers(RequiredInterface aObject) {
+ // TODO do more than equals.
+ if (!(aObject instanceof DefaultRequiredInterface)) {
+ return false;
+ }
+
+ DefaultRequiredInterface descr = (DefaultRequiredInterface) aObject;
+
+ if (required.length != descr.required.length) {
+ return false;
+ }
+
+ String[] interfaces1 = new String[required.length];
+ String[] interfaces2 = new String[required.length];
+
+ for (int i = 0; i < required.length; i++) {
+ interfaces1[i] = required[i].getName();
+ interfaces2[i] = descr.required[i].getName();
+ }
+
+ Arrays.sort(interfaces1);
+ Arrays.sort(interfaces2);
+
+ return Arrays.equals(interfaces1, interfaces2);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(required);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("." + getName() + ":");
+
+ for (Class intf : required) {
+ buf.append("." + intf.getName());
+ }
- private String _name;
- private boolean _optional;
- private Class[] _required;
- private ProvidedInterface _provider;
-
- public DefaultRequiredInterface(String aName, Class aInterface) {
- this(aName, new Class[] { aInterface });
- }
-
- public DefaultRequiredInterface(String aName, Class[] aInterfaces) {
- this(aName, aInterfaces, false);
- }
-
- public DefaultRequiredInterface(String aName, Class aInterface, boolean aIsOptional) {
- this(aName, new Class[] { aInterface }, aIsOptional );
- }
-
-
- public DefaultRequiredInterface(String aName, Class[] aInterfaces, boolean aIsOptional) {
- _name = aName;
- _optional = aIsOptional;
- _required = aInterfaces;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- public boolean isOptional() {
- return _optional;
- }
-
- @Override
- public boolean implementedBy(ProvidedInterface aDescriptor) {
- Class[] provided = aDescriptor.getInterfaceTypes();
- for (Class required : _required) {
- if ( !serviceProvided(required, provided)) {
- return false;
- }
- }
- // all required interfaces are provided.
- return true;
- }
-
- /**
- * Check if the required interface is implemented by one of the provided interfaces.
- * @param aRequired required interface
- * @param aProvided Provided interfaces.
- * @return
- */
- private boolean serviceProvided(Class aRequired, Class[] aProvided) {
- for (Class provided: aProvided) {
- try {
- provided = ReflectionUtils.wrapIfNeeded(provided);
- aRequired = ReflectionUtils.wrapIfNeeded(aRequired);
- provided.asSubclass(aRequired);
- return true;
- } catch (ClassCastException e) {
- // No match, try the next one.
- }
- }
- return false;
- }
-
- @Override
- public ProvidedInterface getProvider() {
- return _provider;
- }
-
- @Override
- public void setProvider(ProvidedInterface aProvider) {
- assert aProvider != null;
- assert implementedBy(aProvider);
- _provider = aProvider;
- }
-
- @Override
- public boolean equals(Object obj) {
- return this == obj;
- }
-
- @Override
- public boolean covers(RequiredInterface obj) {
- // TODO do more than equals.
- if ( !(obj instanceof DefaultRequiredInterface)) {
- return false;
- }
- DefaultRequiredInterface descr = (DefaultRequiredInterface)obj;
- if ( _required.length != descr._required.length ) {
- return false;
- }
- String[] interfaces1 = new String[_required.length];
- String[] interfaces2 = new String[_required.length];
- for (int i = 0; i < _required.length; i++) {
- interfaces1[i] = _required[i].getName();
- interfaces2[i] = descr._required[i].getName();
- }
- Arrays.sort(interfaces1);
- Arrays.sort(interfaces2);
- return Arrays.equals(interfaces1, interfaces2);
- }
-
- @Override
- public int hashCode() {
- return _required.hashCode();
- }
-
- @Override
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("." + getName() + ":");
- for (Class intf: _required) {
- buf.append("." + intf.getName());
- }
- return buf.toString();
- }
+ return buf.toString();
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultScope implements Scope {
+ private List<Scope> parents;
+
+ private Map<String, Object> properties;
+
+ private Map<String, Object> runtimes;
+
+ private Map<ProvidedInterface, ProvidedInterfaceImplementation> provided;
+
+ private List<ProvidedInterface> externallyProvided;
+
+ /**
+ * Creates a new DefaultScope object.
+ *
+ */
+ public DefaultScope(List<ProvidedInterface> aExternallyProvided) {
+ this(aExternallyProvided.toArray(new ProvidedInterface[0]));
+ }
+
+ /**
+ * Creates a new DefaultScope object.
+ *
+ */
+ public DefaultScope(ProvidedInterface[] aExternallyProvided) {
+ this(aExternallyProvided, new ArrayList<Scope>());
+ }
+
+ /**
+ * Creates a new DefaultScope object.
+ *
+ */
+ public DefaultScope(ProvidedInterface[] aExternallyProvided, Scope aParent) {
+ this(aExternallyProvided, Arrays.asList(new Scope[] { aParent }));
+ }
+
+ /**
+ * Creates a new DefaultScope object.
+ *
+ */
+ public DefaultScope(ProvidedInterface[] aExternallyProvided,
+ List<Scope> aParent) {
+ parents = new ArrayList<Scope>(aParent);
+ properties = new HashMap<String, Object>();
+ runtimes = new HashMap<String, Object>();
+ provided = new HashMap<ProvidedInterface, ProvidedInterfaceImplementation>();
+ externallyProvided = new ArrayList<ProvidedInterface>();
+ externallyProvided.addAll(Arrays.asList(aExternallyProvided));
+ }
+
+ @Override
+ public List<ProvidedInterface> getProvidedInterfaces() {
+ return Collections.unmodifiableList(externallyProvided);
+ }
+
+ @Override
+ public Object get(String aKey) {
+ return properties.get(aKey);
+ }
+
+ @Override
+ public void put(String aKey, Object aValue) {
+ properties.put(aKey, aValue);
+ }
+
+ @Override
+ public void addRuntime(Component aComponent, Object aRuntime) {
+ runtimes.put(aComponent.getName(), aRuntime);
+ }
+
+ @Override
+ public Object getRuntime(Component aComponent) {
+ return runtimes.get(aComponent.getName());
+ }
+
+ @Override
+ public Object getRuntime(String aName) {
+ return runtimes.get(aName);
+ }
+
+ @Override
+ synchronized public void publishInterface(ProvidedInterface aInterface,
+ Object aImplementation) {
+ provided.put(aInterface, new ProvidedInterfaceImplementation(
+ aInterface, aImplementation));
+ }
+
+ @Override
+ public <T> T getInterfaceImplementation(ProvidedInterface aInterface,
+ Class<T> aType) {
+ if (aInterface == null) {
+ return null;
+ }
+
+ ProvidedInterfaceImplementation providedIntf = provided.get(aInterface);
+
+ if (providedIntf == null) {
+ for (Scope parent : parents) {
+ T impl = parent.getInterfaceImplementation(aInterface, aType);
+
+ if (impl != null) {
+ return impl;
+ }
+ }
- private List<Scope> _parents;
- private Map<String, Object> _properties;
- private Map<String, Object> _runtimes;
- private Map<ProvidedInterface, ProvidedInterfaceImplementation> _provided;
- private List<ProvidedInterface> _externallyProvided;
-
- public DefaultScope(List<ProvidedInterface>aExternallyProvided) {
- this(aExternallyProvided.toArray(new ProvidedInterface[0]));
- }
-
- public DefaultScope(ProvidedInterface[] aExternallyProvided) {
- this(aExternallyProvided, new ArrayList<Scope>());
- }
-
- public DefaultScope(ProvidedInterface[] aExternallyProvided, Scope aParent) {
- this(aExternallyProvided, Arrays.asList(new Scope[] { aParent }));
- }
-
- public DefaultScope(ProvidedInterface[] aExternallyProvided,
- List<Scope> aParent) {
- _parents = new ArrayList<Scope>(aParent);
- _properties = new HashMap<String, Object>();
- _runtimes = new HashMap<String, Object>();
- _provided = new HashMap<ProvidedInterface, ProvidedInterfaceImplementation>();
- _externallyProvided = new ArrayList<ProvidedInterface>();
- _externallyProvided.addAll(Arrays.asList(aExternallyProvided));
- }
-
- @Override
- public List<ProvidedInterface> getProvidedInterfaces() {
- return Collections.unmodifiableList(_externallyProvided);
- }
-
- @Override
- public Object get(String aKey) {
- return _properties.get(aKey);
- }
-
- @Override
- public void put(String aKey, Object aValue) {
- _properties.put(aKey, aValue);
- }
-
- @Override
- public void addRuntime(Component aComponent, Object aRuntime) {
- _runtimes.put(aComponent.getName(), aRuntime);
- }
-
- @Override
- public Object getRuntime(Component aComponent) {
- return _runtimes.get(aComponent.getName());
- }
-
- @Override
- public Object getRuntime(String aName) {
- return _runtimes.get(aName);
- }
-
- @Override
- synchronized public void publishInterface(ProvidedInterface aInterface,
- Object aImplementation) {
- _provided.put(aInterface, new ProvidedInterfaceImplementation(aInterface,
- aImplementation));
- }
-
- @Override
- public <T> T getInterfaceImplementation(ProvidedInterface aInterface,
- Class<T> aType) {
- if ( aInterface == null ) {
- return null;
- }
- ProvidedInterfaceImplementation provided = _provided.get(aInterface);
- if (provided == null) {
- for (Scope parent : _parents) {
- T impl = parent.getInterfaceImplementation(aInterface, aType);
- if ( impl != null ) {
- return impl;
- }
- }
- return null;
- } else {
- return provided.getImplementation(aType);
- }
- }
+ return null;
+ } else {
+ return providedIntf.getImplementation(aType);
+ }
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.core;
+/**
+ *
+ * @author $author$
+ * @version $Revision: 1.6 $
+ */
public interface NamedInterface {
/**
- * Name for the interface.
+ * Name for the interface.
+ *
*/
String getName();
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.Collection;
/**
- * Represents an interface provided by a component.
- * Different component objects should never share ProvidedInterface instances!
- *
+ * Represents an interface provided by a component. Different component objects
+ * should never share ProvidedInterface instances!
+ *
* @author Erik Brakkee
*/
public interface ProvidedInterface extends NamedInterface {
-
- /**
- * Returns the service type.
- * @return Service type.
- */
- Class[] getInterfaceTypes();
-
-
- /**
- * Determines whether the current provided interface exceeds the given provided interface.
- * In other words if it can provide at least what the given provided interface can provide.
- * @param aInterface Interface to compare to.
- * @return True if the current interface exceeds the given provided interface.
- */
- boolean covers(ProvidedInterface aInterface);
+ /**
+ * Returns the service type.
+ *
+ * @return Service type.
+ */
+ Class[] getInterfaceTypes();
+
+ /**
+ * Determines whether the current provided interface exceeds the given
+ * provided interface. In other words if it can provide at least what the
+ * given provided interface can provide.
+ *
+ * @param aInterface
+ * Interface to compare to.
+ *
+ * @return True if the current interface exceeds the given provided
+ * interface.
+ */
+ boolean covers(ProvidedInterface aInterface);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.system.core;
/**
- * Represents a provided interface together with its implementation.
+ * Represents a provided interface together with its implementation.
*
* @author Erik Brakkee
*/
class ProvidedInterfaceImplementation {
+ private ProvidedInterface provided;
- private ProvidedInterface _provided;
- private Object _implementation;
-
- /**
- * Constructs the object.
- * @param aProvided Provided interface.
- * @param aImplementation Implementation.
- */
- public ProvidedInterfaceImplementation(ProvidedInterface aProvided, Object aImplementation) {
- _provided = aProvided;
- _implementation = aImplementation;
- }
+ private Object implementation;
- /**
- * @return The provided interface.
- */
- public ProvidedInterface getProvided() {
- return _provided;
- }
-
- /**
- * @param <T> Expected type of the implementation.
- * @param aType Type of the implementation.
- * @return Implementation.
- */
- public <T> T getImplementation(Class<T> aType) {
- return (T)_implementation;
- }
+ /**
+ * Constructs the object.
+ *
+ * @param aProvided
+ * Provided interface.
+ * @param aImplementation
+ * Implementation.
+ */
+ public ProvidedInterfaceImplementation(ProvidedInterface aProvided,
+ Object aImplementation) {
+ provided = aProvided;
+ implementation = aImplementation;
+ }
+
+ /**
+ *
+ * @return The provided interface.
+ */
+ public ProvidedInterface getProvided() {
+ return provided;
+ }
+
+ /**
+ *
+ * @param <T>
+ * Expected type of the implementation.
+ * @param aType
+ * Type of the implementation.
+ *
+ * @return Implementation.
+ */
+ public <T> T getImplementation(Class<T> aType) {
+ return (T) implementation;
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.core;
+/**
+ *
+ * @author $author$
+ * @version $Revision: 1.6 $
+ */
public interface RequiredInterface extends NamedInterface {
-
- /**
- * @return True iff the required interface is optional.
- */
- boolean isOptional();
-
-
- /**
- * Checks if the service is provided by a given provided interface.
- * @param aInterface Provided interface.
- * @return
- */
- boolean implementedBy(ProvidedInterface aInterface);
-
- /**
- * Sets the provider of this interface.
- * @param aProvider Provider.
- */
- void setProvider(ProvidedInterface aProvider);
-
- /**
- * Gets the provider interface.
- * @return Provider or null if not set.
- */
- ProvidedInterface getProvider();
-
- /**
- * Determines if the requirements of the current interface are at least those
- * of the given required interface.
- */
- boolean covers(RequiredInterface aInterface);
+ /**
+ *
+ * @return True iff the required interface is optional.
+ */
+ boolean isOptional();
+
+ /**
+ * Checks if the service is provided by a given provided interface.
+ *
+ * @param aInterface
+ * Provided interface.
+ *
+ * @return
+ */
+ boolean implementedBy(ProvidedInterface aInterface);
+
+ /**
+ * Sets the provider of this interface.
+ *
+ * @param aProvider
+ * Provider.
+ */
+ void setProvider(ProvidedInterface aProvider);
+
+ /**
+ * Gets the provider interface.
+ *
+ * @return Provider or null if not set.
+ */
+ ProvidedInterface getProvider();
+
+ /**
+ * Determines if the requirements of the current interface are at least
+ * those of the given required interface.
+ *
+ *
+ */
+ boolean covers(RequiredInterface aInterface);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.List;
/**
- * A scope represents a set of running services and the runtime information for the
- * started components and is (usually) the result of
- * starting a container.
+ * A scope represents a set of running services and the runtime information for
+ * the started components and is (usually) the result of starting a container.
*
* @author Erik Brakkee
*/
public interface Scope {
-
- /**
- * Gets the provided interfaces by this scope.
- * @return Provided interfaces.
- */
- List<ProvidedInterface> getProvidedInterfaces();
-
- /**
- * Adds a key value pair to the scope.
- * @param aKey Key
- * @param aValue Value.
- */
- void put(String aKey, Object aValue);
-
- /**
- * Retrieves a value for the key.
- * @param aKey Key.
- * @return Value.
- */
- Object get(String aKey);
-
- /**
- * Adds the runtime of a started component.
- * @param aComponent Component.
- * @param aRuntime Runtime.
- */
- void addRuntime(Component aComponent, Object aRuntime);
-
- /**
- * Publishes an implementation of a provided interface.
- * @param aInterface Interface that is provided.
- * @param aImplementation Implementation of the interface.
- */
- void publishInterface(ProvidedInterface aInterface, Object aImplementation);
-
- /**
- * Retrieves an implementation of a provided interface.
- * @param aProvided P
- * rovided interface. If it is null then null is returned.
- * @param aType Type of implementation that is expected.
- * @return Retrieved interface.
- */
- <T> T getInterfaceImplementation(ProvidedInterface aProvided, Class<T> aType );
+ /**
+ * Gets the provided interfaces by this scope.
+ *
+ * @return Provided interfaces.
+ */
+ List<ProvidedInterface> getProvidedInterfaces();
- /**
- * Gets the runtime for a component.
- * @param aComponent Component for which we want to get the runtime.
- * @return Runtime.
- */
- Object getRuntime(Component aComponent);
-
- /**
- * Gets the runtime for a component based on the name of the component
- * (excluding its context).
- * @param aName Component name.
- * @return Component name.
- */
- Object getRuntime(String aName);
+ /**
+ * Adds a key value pair to the scope.
+ *
+ * @param aKey
+ * Key
+ * @param aValue
+ * Value.
+ */
+ void put(String aKey, Object aValue);
+
+ /**
+ * Retrieves a value for the key.
+ *
+ * @param aKey
+ * Key.
+ *
+ * @return Value.
+ */
+ Object get(String aKey);
+
+ /**
+ * Adds the runtime of a started component.
+ *
+ * @param aComponent
+ * Component.
+ * @param aRuntime
+ * Runtime.
+ */
+ void addRuntime(Component aComponent, Object aRuntime);
+
+ /**
+ * Publishes an implementation of a provided interface.
+ *
+ * @param aInterface
+ * Interface that is provided.
+ * @param aImplementation
+ * Implementation of the interface.
+ */
+ void publishInterface(ProvidedInterface aInterface, Object aImplementation);
+
+ <T> T getInterfaceImplementation(ProvidedInterface aProvided, Class<T> aType);
+
+ /**
+ * Gets the runtime for a component.
+ *
+ * @param aComponent
+ * Component for which we want to get the runtime.
+ *
+ * @return Runtime.
+ */
+ Object getRuntime(Component aComponent);
+
+ /**
+ * Gets the runtime for a component based on the name of the component
+ * (excluding its context).
+ *
+ * @param aName
+ * Component name.
+ *
+ * @return Component name.
+ */
+ Object getRuntime(String aName);
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/**
* Exception thrown when an error occurs in assembling the systems.
- *
+ *
* @author Erik Brakkee
*/
public class SystemAssemblyException extends RuntimeException {
+ /**
+ * Constructs the exception.
+ *
+ * @param aMsg
+ * Message.
+ */
+ public SystemAssemblyException(String aMsg) {
+ super(aMsg);
+ }
- /**
- * Constructs the exception.
- * @param aMsg Message.
- */
- public SystemAssemblyException(String aMsg) {
- super(aMsg);
- }
-
- /**
- * Constructs the exception.
- * @param aMsg Message
- * @param aCause Cause.
- */
- public SystemAssemblyException(String aMsg, Throwable aCause) {
- super(aMsg, aCause);
- }
+ /**
+ * Constructs the exception.
+ *
+ * @param aMsg
+ * Message
+ * @param aCause
+ * Cause.
+ */
+ public SystemAssemblyException(String aMsg, Throwable aCause) {
+ super(aMsg, aCause);
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.ArrayList;
import java.util.List;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class CompositeEdgeFilter implements EdgeFilter {
-
- private List<EdgeFilter> _filters;
-
- public CompositeEdgeFilter() {
- _filters = new ArrayList<EdgeFilter>();
+ private List<EdgeFilter> filters;
+
+ /**
+ * Creates a new CompositeEdgeFilter object.
+ */
+ public CompositeEdgeFilter() {
+ filters = new ArrayList<EdgeFilter>();
}
-
- public void add(EdgeFilter aFilter) {
- _filters.add(aFilter);
+
+ public void add(EdgeFilter aFilter) {
+ filters.add(aFilter);
}
@Override
public boolean isViolated(Edge aEdge) {
- for (EdgeFilter filter: _filters) {
- if ( filter.isViolated(aEdge) ) {
- return true;
+ for (EdgeFilter filter : filters) {
+ if (filter.isViolated(aEdge)) {
+ return true;
}
}
- return false;
- }
+ return false;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.system.graph;
/**
- * Represents an application-independent edge of a graph.
- * Applications might choose to implement the Edge interface
- * directly.
+ * Represents an application-independent edge of a graph. Applications might
+ * choose to implement the Edge interface directly.
*
* @author Erik Brakkee
*/
public class DefaultEdge implements Edge {
-
- private Node _from;
- private Node _to;
-
- public DefaultEdge(Node aFrom, Node aTo) {
- _from = aFrom;
- _to = aTo;
+ private Node from;
+
+ private Node to;
+
+ /**
+ * Creates a new DefaultEdge object.
+ *
+ */
+ public DefaultEdge(Node aFrom, Node aTo) {
+ from = aFrom;
+ to = aTo;
}
@Override
public Node getFrom() {
- return _from;
+ return from;
}
@Override
public Node getTo() {
- return _to;
+ return to;
}
-
+
@Override
public String toString() {
- return "Edge(" + _from.getName() + ", " + _to.getName() + ")";
+ return "Edge(" + from.getName() + ", " + to.getName() + ")";
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.system.graph;
/**
- * Default application-independent node. Specific applications of the graph might
- * implement the Node interface directly.
+ * Default application-independent node. Specific applications of the graph
+ * might implement the Node interface directly.
+ *
* @author Erik Brakkee
- *
*/
public class DefaultNode implements Node {
-
- private String _name;
-
+ private String name;
+
/**
- * Constructs the node.
- * @param aName Node name.
+ * Constructs the node.
+ *
+ * @param aName
+ * Node name.
*/
- public DefaultNode(String aName) {
- _name = aName;
+ public DefaultNode(String aName) {
+ name = aName;
}
/**
- * Returns the node name.
+ * Returns the node name.
+ *
*/
@Override
public String getName() {
- return _name;
+ return name;
}
@Override
public boolean equals(Object aObj) {
- if ( !(aObj instanceof Node)) {
- return false;
+ if (!(aObj instanceof Node)) {
+ return false;
}
- Node node = (Node)aObj;
- return _name.equals(node.getName());
+
+ Node node = (Node) aObj;
+
+ return name.equals(node.getName());
}
-
+
@Override
public int hashCode() {
- return _name.hashCode();
+ return name.hashCode();
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.system.graph;
/**
- * Represents an edge of a graph.
+ * Represents an edge of a graph.
*
* @author Erik Brakkee
*/
public interface Edge {
-
/**
- * @return The from part of the edge.
+ *
+ *
+ * @return The from part of the edge.
*/
Node getFrom();
-
+
/**
- * @return The to part of the edge.
+ *
+ *
+ * @return The to part of the edge.
*/
Node getTo();
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.List;
/**
- * Edge factory used to extend a graph with new edges.
+ * Edge factory used to extend a graph with new edges.
+ *
* @author Erik Brakkee
- *
- * @param <NodeType> Type of node.
+ *
+ * @param <NodeType>
+ * Type of node.
*/
public interface EdgeFactory<NodeType extends Node> {
/**
- * Computes a number of new edges to be added to the graph.
- * @param aFrom From node.
- * @param aTo To node.
- * @return List of edges from the from to the to node.
+ * Computes a number of new edges to be added to the graph.
+ *
+ * @param aFrom
+ * From node.
+ * @param aTo
+ * To node.
+ * @return List of edges from the from to the to node.
*/
- List<Edge> create(NodeType aFrom, NodeType aTo);
+ List<Edge> create(NodeType aFrom, NodeType aTo);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph;
+/**
+ *
+ * @author $author$
+ * @version $Revision: 1.6 $
+ */
public interface EdgeFilter {
-
- boolean isViolated(Edge aEdge);
+ boolean isViolated(Edge aEdge);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ *
+ */
public class EdgeSelector<FromType extends Node, ToType extends Node> {
-
- public static interface Selector<FromType extends Node, ToType extends Node> {
- void execute(FromType aFrom, ToType aTo);
- }
-
- private Class<FromType> _fromType;
- private Class<ToType> _toType;
-
+ private Class<FromType> fromType;
+
+ private Class<ToType> toType;
+
+ /**
+ * Creates a new EdgeSelector object.
+ *
+ */
public EdgeSelector(Class<FromType> aFrom, Class<ToType> aTo) {
- _fromType = aFrom;
- _toType = aTo;
+ fromType = aFrom;
+ toType = aTo;
+ }
+
+ public void execute(Selector<FromType, ToType> aSelector, Edge aEdge) {
+ if (fromType.isInstance(aEdge.getFrom()) &&
+ toType.isInstance(aEdge.getTo())) {
+ aSelector.execute((FromType) aEdge.getFrom(), (ToType) aEdge
+ .getTo());
+ }
}
- public void execute(Selector<FromType,ToType> aSelector, Edge aEdge) {
- if ( _fromType.isInstance(aEdge.getFrom()) && _toType.isInstance(aEdge.getTo())) {
- aSelector.execute((FromType)aEdge.getFrom(), (ToType)aEdge.getTo());
- }
+ public static interface Selector<FromType extends Node, ToType extends Node> {
+ void execute(FromType aFrom, ToType aTo);
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph;
import java.util.ArrayList;
* @author Erik Brakkee
*/
public class Graph {
+ private List<Node> nodes;
- private List<Node> _nodes;
- private List<Edge> _edges;
+ private List<Edge> edges;
/**
* Constructs the graph.
*/
public Graph() {
- _nodes = new ArrayList<Node>();
- _edges = new ArrayList<Edge>();
+ nodes = new ArrayList<Node>();
+ edges = new ArrayList<Edge>();
}
/**
*
* @param aNode
* Node to add.
+ *
* @throws IllegalArgumentException
* In case the node already exists. Node equality is checked
* using <code>equals</code>.
*/
public void addNode(Node aNode) {
- if (_nodes.contains(aNode)) {
- throw new IllegalArgumentException("Node '" + aNode.getName()
- + "' already exists");
+ if (nodes.contains(aNode)) {
+ throw new IllegalArgumentException("Node '" + aNode.getName() +
+ "' already exists");
}
- _nodes.add(aNode);
+
+ nodes.add(aNode);
}
/**
*
* @param aName
* Node name.
+ *
* @return Node or null if not found.
*/
public Node findNode(String aName) {
- for (Node node : _nodes) {
+ for (Node node : nodes) {
if (node.getName().equals(aName)) {
return node;
}
}
+
return null;
}
*
* @param aNode
* Node to remove.
+ *
* @return True iff the node was removed.
+ *
* @throws IllegalArgumentException
* In case there are edges of which the node is a part.
*/
public boolean removeNode(Node aNode) {
if (!findOutgoing(aNode).isEmpty() || !findIncoming(aNode).isEmpty()) {
- throw new IllegalArgumentException("Cannot remove node '"
- + aNode.getName()
- + "' because it is connected to one or more edges");
+ throw new IllegalArgumentException("Cannot remove node '" +
+ aNode.getName() +
+ "' because it is connected to one or more edges");
}
- return _nodes.remove(aNode);
+
+ return nodes.remove(aNode);
}
/**
*
* @param aEdge
* Edge to add.
+ *
* @throws IllegalArgumentException
* In case one of the nodes of the edges is not part of the
* graph or if the same edge (as determined by
* {@link #equals(Object)} is already a part of the graph.
*/
public void addEdge(Edge aEdge) {
- if (_edges.contains(aEdge)) {
- throw new IllegalArgumentException("Edge '" + aEdge
- + "' already exists");
+ if (edges.contains(aEdge)) {
+ throw new IllegalArgumentException("Edge '" + aEdge +
+ "' already exists");
}
- if (!_nodes.contains(aEdge.getFrom())) {
- throw new IllegalArgumentException("From node '" + aEdge.getFrom()
- + "' from edge '" + aEdge + "' is not part of the graph");
+
+ if (!nodes.contains(aEdge.getFrom())) {
+ throw new IllegalArgumentException("From node '" + aEdge.getFrom() +
+ "' from edge '" + aEdge + "' is not part of the graph");
}
- if (!_nodes.contains(aEdge.getTo())) {
- throw new IllegalArgumentException("To node '" + aEdge.getTo()
- + "' from edge '" + aEdge + "' is not part of the graph");
+
+ if (!nodes.contains(aEdge.getTo())) {
+ throw new IllegalArgumentException("To node '" + aEdge.getTo() +
+ "' from edge '" + aEdge + "' is not part of the graph");
}
- _edges.add(aEdge);
+
+ edges.add(aEdge);
}
/**
- * Removes an edge.
- * @param aEdge Edge to remove.
- * @return True if the edge was removed.
+ * Removes an edge.
+ *
+ * @param aEdge
+ * Edge to remove.
+ *
+ * @return True if the edge was removed.
*/
public boolean removeEdge(Edge aEdge) {
- return _edges.remove(aEdge);
+ return edges.remove(aEdge);
}
/**
- * Adds a number of edges.
- * @param aEdges Edges to add.
+ * Adds a number of edges.
+ *
+ * @param aEdges
+ * Edges to add.
*/
public void addEdges(List<Edge> aEdges) {
for (Edge edge : aEdges) {
}
/**
- * Gets the nodes.
- * @return Copy of the list of nodes of the graph.
+ * Gets the nodes.
+ *
+ * @return Copy of the list of nodes of the graph.
*/
public List<Node> getNodes() {
- return new ArrayList<Node>(_nodes);
+ return new ArrayList<Node>(nodes);
}
/**
- * Gets the edges.
- * @return Copy of the list of edges of the graph.
+ * Gets the edges.
+ *
+ * @return Copy of the list of edges of the graph.
*/
public List<Edge> getEdges() {
- return new ArrayList<Edge>(_edges);
+ return new ArrayList<Edge>(edges);
}
/**
- * Extends the graph with edges using an edge factory. All combinations of
- * nodes are passed to the factory which creates additional edges.
- * @param aFactory Edge factory.
+ * Extends the graph with edges using an edge factory. All combinations of
+ * nodes are passed to the factory which creates additional edges.
+ *
+ * @param aFactory
+ * Edge factory.
*/
public void extend(EdgeFactory aFactory) {
- for (Node from : _nodes) {
- for (Node to : _nodes) {
- _edges.addAll(aFactory.create(from, to));
+ for (Node from : nodes) {
+ for (Node to : nodes) {
+ edges.addAll(aFactory.create(from, to));
}
}
}
-
+
/**
- * Applies a filter to the graph for removing elements.
- * @param aFilter Filter to apply.
+ * Applies a filter to the graph for removing elements.
+ *
+ * @param aFilter
+ * Filter to apply.
*/
public void applyFilter(EdgeFilter aFilter) {
- for (Iterator<Edge> edge = _edges.iterator(); edge.hasNext(); ) {
- if (aFilter.isViolated(edge.next())) {
+ for (Iterator<Edge> edge = edges.iterator(); edge.hasNext();) {
+ if (aFilter.isViolated(edge.next())) {
edge.remove();
}
}
}
/**
- * Finds all outgoing edges of a node. More specifically, finds
- * all edges <code>e</code> for which <code>e.getFrom().getName() = aNode.getName()</code>.
- * @param aNode Node for which to find outgoing edges.
- * @return List of outgoing edges.
+ * Finds all outgoing edges of a node. More specifically, finds all edges
+ * <code>e</code> for which <code>e.getFrom().getName() =
+ * aNode.getName()</code>.
+ *
+ * @param aNode
+ * Node for which to find outgoing edges.
+ *
+ * @return List of outgoing edges.
*/
public List<Edge> findOutgoing(Node aNode) {
List<Edge> result = new ArrayList<Edge>();
- for (Edge edge : _edges) {
+
+ for (Edge edge : edges) {
if (edge.getFrom().getName().equals(aNode.getName())) {
result.add(edge);
}
}
+
return result;
}
/**
- * Finds all incoming edges of a node.
- * More specifically, finds
- * all edges <code>e</code> for which <code>e.getTo().getName() = aNode.getName()</code>.
- * @param aNode Node for which to find incoming edges.
- * @return List of incoming edges.
+ * Finds all incoming edges of a node. More specifically, finds all edges
+ * <code>e</code> for which <code>e.getTo().getName() =
+ * aNode.getName()</code>.
+ *
+ * @param aNode
+ * Node for which to find incoming edges.
+ *
+ * @return List of incoming edges.
*/
public List<Edge> findIncoming(Node aNode) {
List<Edge> result = new ArrayList<Edge>();
- for (Edge edge : _edges) {
+
+ for (Edge edge : edges) {
if (edge.getTo().getName().equals(aNode.getName())) {
result.add(edge);
}
}
+
return result;
}
/**
- * Implements a visitor design pattern.
- * This loops over all nodes and all edges and invokes the appropriate visit
- * methods on the visitor.
- * @param aVisitor Visitor.
+ * Implements a visitor design pattern. This loops over all nodes and all
+ * edges and invokes the appropriate visit methods on the visitor.
+ *
+ * @param aVisitor
+ * Visitor.
*/
public void accept(Visitor aVisitor) {
List<Node> nodes = getNodes(); // copy to make sure the visitor can
// modify the
// list of nodes as part of the loop.
+
List<Edge> edges = getEdges(); // copy ..... (see above).
for (Node node : nodes) {
aVisitor.visitNode(node);
}
+
for (Edge edge : edges) {
aVisitor.visitEdge(edge);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.system.graph;
/**
- * Represents a node in a graph.
+ * Represents a node in a graph.
+ *
* @author Erik Brakkee
*/
public interface Node {
-
/**
- * Gets the node name uniquely identifying the node in the graph.
- * @return Node name.
+ * Gets the node name uniquely identifying the node in the graph.
+ *
+ * @return Node name.
*/
String getName();
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.wamblee.system.graph;
/**
- * Visitor of a graph.
+ * Visitor of a graph.
+ *
* @author Erik Brakkee.
- *
+ *
*/
public interface Visitor {
-
/**
* Visits a node. Called by {@link Graph#accept(Visitor)}.
- * @param aNode Node to visit.
+ *
+ * @param aNode
+ * Node to visit.
*/
- void visitNode(Node aNode);
-
+ void visitNode(Node aNode);
+
/**
* Visits a node. Called by {@link Graph#accept(Visitor)}.
- * @param aEdge Edge to visit.
+ *
+ * @param aEdge
+ * Edge to visit.
*/
- void visitEdge(Edge aEdge);
+ void visitEdge(Edge aEdge);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph.component;
-import java.util.List;
-
import org.wamblee.system.core.SystemAssemblyException;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.Graph;
import org.wamblee.system.graph.Node;
import org.wamblee.system.graph.Visitor;
+import java.util.List;
+
/**
- * Visitor that checks whether all externally provided interfaces are actually provided
- * by any of the internal components.
+ * Visitor that checks whether all externally provided interfaces are actually
+ * provided by any of the internal components.
*
* @author Erik Brakkee
- *
*/
public class CheckExternallyProvidedVisitor implements Visitor {
-
- private Graph _graph;
+ private Graph graph;
/**
- * Constructs the visitor.
- * @param aGraph Component graph.
+ * Constructs the visitor.
+ *
+ * @param aGraph
+ * Component graph.
*/
- public CheckExternallyProvidedVisitor(Graph aGraph) {
- _graph = aGraph;
+ public CheckExternallyProvidedVisitor(Graph aGraph) {
+ graph = aGraph;
}
@Override
@Override
public void visitNode(Node aNode) {
- if ( aNode instanceof ExternalProvidedInterfaceNode) {
- ExternalProvidedInterfaceNode provided = (ExternalProvidedInterfaceNode) aNode;
- List<Edge> edges = _graph.findOutgoing(provided);
- if ( edges.size() > 2 ) {
- createDuplicateException("External provided interfaces has multiple internal matches", aNode, edges);
+ if (aNode instanceof ExternalProvidedInterfaceNode) {
+ ExternalProvidedInterfaceNode provided = (ExternalProvidedInterfaceNode) aNode;
+ List<Edge> edges = graph.findOutgoing(provided);
+
+ if (edges.size() > 2) {
+ createDuplicateException(
+ "External provided interfaces has multiple internal matches",
+ aNode, edges);
}
- if ( edges.size() == 0 ) {
- throw new SystemAssemblyException(aNode + ": external provded interface is not provided by any of the internal components");
+
+ if (edges.size() == 0) {
+ throw new SystemAssemblyException(
+ aNode +
+ ": external provded interface is not provided by any of the internal components");
}
}
}
-
- private void createDuplicateException(String aMsg, Node aNode, List<Edge> edges) {
+
+ private void createDuplicateException(String aMsg, Node aNode,
+ List<Edge> aEdges) {
StringBuffer buf = new StringBuffer();
- buf.append(aNode
- + ": " + aMsg + ": ");
- for (Edge edge : edges) {
+ buf.append(aNode + ": " + aMsg + ": ");
+
+ for (Edge edge : aEdges) {
buf.append(edge.getTo() + "/ ");
}
+
throw new SystemAssemblyException(buf.toString());
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
-import java.util.List;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.wamblee.system.core.SystemAssemblyException;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.Graph;
import org.wamblee.system.graph.Node;
import org.wamblee.system.graph.Visitor;
+import java.util.List;
+
/**
* Visitor that checks whether all required external interfaces of the container
* are provided.
*
* @author Erik Brakkee
- *
*/
public class CheckExternallyRequiredVisitor implements Visitor {
+ private static final Log LOG = LogFactory.getLog(CheckExternallyRequiredVisitor.class);
- private Log LOG = LogFactory.getLog(CheckExternallyRequiredVisitor.class);
-
- private Graph _graph;
+ private Graph graph;
+ /**
+ * Creates a new CheckExternallyRequiredVisitor object.
+ *
+ */
public CheckExternallyRequiredVisitor(Graph aGraph) {
- _graph = aGraph;
+ graph = aGraph;
}
@Override
public void visitNode(Node aNode) {
if (aNode instanceof ExternalRequiredInterfaceNode) {
ExternalRequiredInterfaceNode required = (ExternalRequiredInterfaceNode) aNode;
- if (!required.getRequired().isOptional()
- && required.getRequired().getProvider() == null) {
- throw new SystemAssemblyException(aNode
- + ": External required interface is not provided");
+
+ if (!required.getRequired().isOptional() &&
+ (required.getRequired().getProvider() == null)) {
+ throw new SystemAssemblyException(aNode +
+ ": External required interface is not provided");
}
- List<Edge> edges = _graph.findIncoming(aNode);
+ List<Edge> edges = graph.findIncoming(aNode);
if (edges.isEmpty()) {
LOG.warn(aNode + ": Superfluous required interface");
}
+
for (Edge edge : edges) {
Node from = edge.getFrom();
assert from instanceof RequiredInterfaceNode;
- RequiredInterfaceNode reqNode = (RequiredInterfaceNode)from;
- if (!reqNode.getRequired().isOptional()
- && required.getRequired().isOptional()) {
+
+ RequiredInterfaceNode reqNode = (RequiredInterfaceNode) from;
+
+ if (!reqNode.getRequired().isOptional() &&
+ required.getRequired().isOptional()) {
throw new SystemAssemblyException(
- aNode
- + ": externally required interface is optional but a corresponding internal required interface is mandatory: "
- + reqNode);
+ aNode +
+ ": externally required interface is optional but a corresponding internal required interface is mandatory: " +
+ reqNode);
}
}
}
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
-import java.util.List;
-
import org.wamblee.system.core.SystemAssemblyException;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.Graph;
import org.wamblee.system.graph.Node;
import org.wamblee.system.graph.Visitor;
+import java.util.List;
+
/**
* Visitor that checks whether required and provided interfaces are matched
* appropriately:
* <ul>
- * <li>Each required interface is connected to at most one provided interface
- * </li>
+ * <li>Each required interface is connected to at most one provided interface</li>
* <li>Required interfaces that are not optional must be connected to precisely
* one provided interface</li>
* </ul>
*
* @author Erik Brakkee
- *
*/
public class CheckRequiredProvidedMultiplicityVisitor implements Visitor {
+ private Graph graph;
- private Graph _graph;
-
+ /**
+ * Creates a new CheckRequiredProvidedMultiplicityVisitor object.
+ *
+ */
public CheckRequiredProvidedMultiplicityVisitor(Graph aGraph) {
- _graph = aGraph;
+ graph = aGraph;
}
@Override
public void visitNode(Node aNode) {
if (aNode instanceof RequiredInterfaceNode) {
RequiredInterfaceNode required = (RequiredInterfaceNode) aNode;
- List<Edge> edges = _graph.findOutgoing(aNode);
+ List<Edge> edges = graph.findOutgoing(aNode);
+
if (edges.size() > 1) {
- createDuplicateException("Multiple providers of required interface found", aNode, edges);
+ createDuplicateException(
+ "Multiple providers of required interface found", aNode,
+ edges);
}
- if (edges.size() == 0 && !required.getRequired().isOptional()) {
+
+ if ((edges.size() == 0) && !required.getRequired().isOptional()) {
throw new SystemAssemblyException(
- aNode
- + ": mandatpory required interface not provided by other components started earlier");
+ aNode +
+ ": mandatpory required interface not provided by other components started earlier");
}
- } else if ( aNode instanceof ExternalProvidedInterfaceNode) {
- List<Edge> edges = _graph.findOutgoing(aNode);
- if ( edges.size() > 1) {
- createDuplicateException("multiple internal matches for externally provided interface", aNode, edges);
+ } else if (aNode instanceof ExternalProvidedInterfaceNode) {
+ List<Edge> edges = graph.findOutgoing(aNode);
+
+ if (edges.size() > 1) {
+ createDuplicateException(
+ "multiple internal matches for externally provided interface",
+ aNode, edges);
}
- if ( edges.size() == 0 ) {
- throw new SystemAssemblyException(aNode + ": external provided interface is not provided internally");
+
+ if (edges.size() == 0) {
+ throw new SystemAssemblyException(aNode +
+ ": external provided interface is not provided internally");
}
}
}
- private void createDuplicateException(String aMsg, Node aNode, List<Edge> edges) {
+ private void createDuplicateException(String aMsg, Node aNode,
+ List<Edge> aEdges) {
StringBuffer buf = new StringBuffer();
- buf.append(aNode
- + ": " + aMsg + ": ");
- for (Edge edge : edges) {
+ buf.append(aNode + ": " + aMsg + ": ");
+
+ for (Edge edge : aEdges) {
buf.append(edge.getTo() + "/ ");
}
+
throw new SystemAssemblyException(buf.toString());
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph.component;
-import java.util.ArrayList;
-import java.util.List;
-
import org.wamblee.system.core.SystemAssemblyException;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.Graph;
import org.wamblee.system.graph.Node;
import org.wamblee.system.graph.Visitor;
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * Checks whether the given component graph can be started in component
- * order without any missing dependencies.
+ * Checks whether the given component graph can be started in component order
+ * without any missing dependencies.
+ *
* @author Erik Brakkee
- *
*/
public class CheckStartupDependenciesVisitor implements Visitor {
-
- private Graph _graph;
- private List<Node> _available;
+ private Graph graph;
+
+ private List<Node> available;
/**
- * Constructs the visitor.
- * @param aGraph Graph.
+ * Constructs the visitor.
+ *
+ * @param aGraph
+ * Graph.
*/
- public CheckStartupDependenciesVisitor(Graph aGraph) {
- _graph = aGraph;
- _available = new ArrayList<Node>();
+ public CheckStartupDependenciesVisitor(Graph aGraph) {
+ graph = aGraph;
+ available = new ArrayList<Node>();
}
@Override
@Override
public void visitNode(Node aNode) {
- List<Edge> edges = _graph.findOutgoing(aNode);
-
+ List<Edge> edges = graph.findOutgoing(aNode);
+
// check dependencies.
- for (Edge edge: edges) {
+ for (Edge edge : edges) {
Node dep = edge.getTo();
- if ( !_available.contains(dep)) {
- throw new SystemAssemblyException(aNode + ": required dependency '" + dep + "' was not started");
+
+ if (!available.contains(dep)) {
+ throw new SystemAssemblyException(aNode +
+ ": required dependency '" + dep + "' was not started");
}
}
-
- _available.add(aNode);
- }
+ available.add(aNode);
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph.component;
-import java.util.ArrayList;
-import java.util.List;
-
import org.wamblee.general.Pair;
+
import org.wamblee.system.core.Component;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.graph.Graph;
import org.wamblee.system.graph.Node;
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * Represents a component graph and provides the bridge from the
- * component model to a graph model. The graph model is easier
- * to work with to implement specific actions and validations than
- * the component model.
+ * Represents a component graph and provides the bridge from the component model
+ * to a graph model. The graph model is easier to work with to implement
+ * specific actions and validations than the component model.
*/
public class ComponentGraph extends Graph {
-
- private boolean _isLinked;
- private CompositeEdgeFilter _edgeFilter;
+ private boolean isLinked;
+
+ private CompositeEdgeFilter edgeFilter;
/**
- * Constructs an empty component graph.
+ * Constructs an empty component graph.
*/
public ComponentGraph() {
- _isLinked = false;
- _edgeFilter = new CompositeEdgeFilter();
+ isLinked = false;
+ edgeFilter = new CompositeEdgeFilter();
}
-
+
/**
- * Adds an externally required interface of a container.
- * This should be called before any components of the container are
- * added.
- * @param aComponent Component requiring the interface.
- * @param aInterface Required interface.
+ * Adds an externally required interface of a container. This should be
+ * called before any components of the container are added.
+ *
+ * @param aComponent
+ * Component requiring the interface.
+ * @param aInterface
+ * Required interface.
*/
- public void addRequiredInterface(Component aComponent, RequiredInterface aInterface) {
+ public void addRequiredInterface(Component aComponent,
+ RequiredInterface aInterface) {
addNode(new ExternalRequiredInterfaceNode(aComponent, aInterface));
}
-
+
/**
- * Adds an externally provided interface of a container.
- * This should be called after all components of the container have been added.
- * @param aComponent Component providing the interface.
- * @param aInterface Provided interface.
+ * Adds an externally provided interface of a container. This should be
+ * called after all components of the container have been added.
+ *
+ * @param aComponent
+ * Component providing the interface.
+ * @param aInterface
+ * Provided interface.
*/
- public void addProvidedInterface(Component aComponent, ProvidedInterface aInterface) {
+ public void addProvidedInterface(Component aComponent,
+ ProvidedInterface aInterface) {
addNode(new ExternalProvidedInterfaceNode(aComponent, aInterface));
}
-
+
/**
- * Validates the component graph.
+ * Validates the component graph.
*/
- public void validate() {
+ public void validate() {
extend(new RequiredProvidedEdgeFactory());
- applyFilter(_edgeFilter);
+ applyFilter(edgeFilter);
accept(new CheckRequiredProvidedMultiplicityVisitor(this));
- accept(new CheckExternallyRequiredVisitor(this));
+ accept(new CheckExternallyRequiredVisitor(this));
accept(new CheckExternallyProvidedVisitor(this));
accept(new CheckStartupDependenciesVisitor(this));
}
-
+
/**
- * Links provided and required interfaces together in the component
- * model based on the graph model.
+ * Links provided and required interfaces together in the component model
+ * based on the graph model.
*/
public void link() {
- if ( _isLinked ) {
- return;
+ if (isLinked) {
+ return;
}
+
accept(new LinkVisitor());
- _isLinked = true;
+ isLinked = true;
}
-
+
/**
- * Finds a list of mappings of external provided interface to internal provided interface.
+ * Finds a list of mappings of external provided interface to internal
+ * provided interface.
*
- * @return List of pairs of external to internal interface.
+ * @return List of pairs of external to internal interface.
*/
- public List<Pair<ProvidedInterface, ProvidedInterface>> findExternalProvidedInterfaceMapping() {
- List<Pair<ProvidedInterface, ProvidedInterface>> result =
- new ArrayList<Pair<ProvidedInterface,ProvidedInterface>>();
- for (Edge edge: getEdges()) {
- if ( edge.getFrom() instanceof ExternalProvidedInterfaceNode &&
- edge.getTo() instanceof ProvidedInterfaceNode ) {
- result.add(new Pair<ProvidedInterface,ProvidedInterface>(
- ((ExternalProvidedInterfaceNode)edge.getFrom()).getProvided(),
- ((ProvidedInterfaceNode)edge.getTo()).getProvided()
- ));
+ public List<Pair<ProvidedInterface, ProvidedInterface>> findExternalProvidedInterfaceMapping() {
+ List<Pair<ProvidedInterface, ProvidedInterface>> result = new ArrayList<Pair<ProvidedInterface, ProvidedInterface>>();
+
+ for (Edge edge : getEdges()) {
+ if (edge.getFrom() instanceof ExternalProvidedInterfaceNode &&
+ edge.getTo() instanceof ProvidedInterfaceNode) {
+ result.add(new Pair<ProvidedInterface, ProvidedInterface>(
+ ((ExternalProvidedInterfaceNode) edge.getFrom())
+ .getProvided(), ((ProvidedInterfaceNode) edge.getTo())
+ .getProvided()));
}
}
- return result;
+
+ return result;
}
-
+
/**
- * Adds a component by adding required interfaces, components, and
- * provided interfaces.
- * @param aComponent Component to add.
+ * Adds a component by adding required interfaces, components, and provided
+ * interfaces.
+ *
+ * @param aComponent
+ * Component to add.
*/
- public void addComponent(Component<?> aComponent) {
- // Add required interfaces.
+ public void addComponent(Component<?> aComponent) {
+ // Add required interfaces.
Node compNode = new ComponentNode(aComponent);
List<Node> requiredNodes = new ArrayList<Node>();
- for (RequiredInterface required: aComponent.getRequiredInterfaces()) {
- Node reqNode = new RequiredInterfaceNode(aComponent, required);
+
+ for (RequiredInterface required : aComponent.getRequiredInterfaces()) {
+ Node reqNode = new RequiredInterfaceNode(aComponent, required);
addNode(reqNode);
requiredNodes.add(reqNode);
}
+
// Add the component
addNode(compNode);
-
- // Edges from component to required interface.
- for (Node reqNode: requiredNodes) {
+
+ // Edges from component to required interface.
+ for (Node reqNode : requiredNodes) {
addEdge(new DefaultEdge(compNode, reqNode));
}
-
+
// Add provided interfaces
List<Node> providedNodes = new ArrayList<Node>();
- for (ProvidedInterface provided: aComponent.getProvidedInterfaces()) {
- Node provNode = new ProvidedInterfaceNode(aComponent, provided);
+
+ for (ProvidedInterface provided : aComponent.getProvidedInterfaces()) {
+ Node provNode = new ProvidedInterfaceNode(aComponent, provided);
addNode(provNode);
providedNodes.add(provNode);
}
-
+
// Edges from provided interface to component
- for (Node provNode: providedNodes) {
+ for (Node provNode : providedNodes) {
addEdge(new DefaultEdge(provNode, compNode));
}
}
public void addEdgeFilter(CompositeEdgeFilter aEdgeFilter) {
- _edgeFilter.add(aEdgeFilter);
+ edgeFilter.add(aEdgeFilter);
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.graph.Node;
/**
- * Represents a component node.
- * @author Erik Brakkee.
- *
+ * Represents a component node.
+ *
+ * @author Erik Brakkee.
*/
public class ComponentNode implements Node {
-
- private Component<?> _component;
-
- public ComponentNode(Component<?> aComponent) {
- _component = aComponent;
+ private Component<?> component;
+
+ /**
+ * Creates a new ComponentNode object.
+ *
+ */
+ public ComponentNode(Component<?> aComponent) {
+ component = aComponent;
}
@Override
public String getName() {
- return _component.getQualifiedName();
+ return component.getQualifiedName();
}
-
+
public Component<?> getComponent() {
- return _component;
+ return component;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
import org.wamblee.system.graph.Edge;
* container.
*
* @author Erik Brakkee
- *
*/
public class ConnectExternalProvidedProvidedFilter implements EdgeFilter {
+ private String externalProvided;
+
+ private String component;
- private String _externalProvided;
- private String _component;
- private String _provided;
+ private String provided;
- public ConnectExternalProvidedProvidedFilter(String aExternalProvided, String aComponent,
- String aProvided) {
- _externalProvided = aExternalProvided;
- _component = aComponent;
- _provided = aProvided;
- if ( _externalProvided == null ) {
- throw new IllegalArgumentException("External provided interface name must be specified.");
+ /**
+ * Creates a new ConnectExternalProvidedProvidedFilter object.
+ *
+ */
+ public ConnectExternalProvidedProvidedFilter(String aExternalProvided,
+ String aComponent, String aProvided) {
+ externalProvided = aExternalProvided;
+ component = aComponent;
+ provided = aProvided;
+
+ if (externalProvided == null) {
+ throw new IllegalArgumentException(
+ "External provided interface name must be specified.");
}
- if ( _component == null ) {
- throw new IllegalArgumentException("Component name must be specified");
+
+ if (component == null) {
+ throw new IllegalArgumentException(
+ "Component name must be specified");
}
- if ( _provided == null ) {
- throw new IllegalArgumentException("Provided interface name of internal component must be specified");
+
+ if (provided == null) {
+ throw new IllegalArgumentException(
+ "Provided interface name of internal component must be specified");
}
}
@Override
public boolean isViolated(Edge aEdge) {
- if (aEdge.getFrom() instanceof ExternalProvidedInterfaceNode
- && aEdge.getTo() instanceof ProvidedInterfaceNode) {
+ if (aEdge.getFrom() instanceof ExternalProvidedInterfaceNode &&
+ aEdge.getTo() instanceof ProvidedInterfaceNode) {
return isViolated((ExternalProvidedInterfaceNode) aEdge.getFrom(),
- (ProvidedInterfaceNode) aEdge.getTo());
+ (ProvidedInterfaceNode) aEdge.getTo());
}
+
return false;
}
private boolean isViolated(ExternalProvidedInterfaceNode aFrom,
- ProvidedInterfaceNode aTo) {
- if ( !aFrom.getName().equals(_externalProvided)) {
+ ProvidedInterfaceNode aTo) {
+ if (!aFrom.getName().equals(externalProvided)) {
return false; // wrong provided interface.
}
- if ( aTo.getComponent().getName().equals(_component) &&
- aTo.getProvided().getName().equals(_provided) ) {
- return false; // ok
+
+ if (aTo.getComponent().getName().equals(component) &&
+ aTo.getProvided().getName().equals(provided)) {
+ return false; // ok
}
- return true;
+
+ return true;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
import org.wamblee.system.graph.Edge;
* container.
*
* @author Erik Brakkee
- *
*/
public class ConnectRequiredExternallyRequiredEdgeFilter implements EdgeFilter {
+ private String client;
+
+ private String required;
- private String _client;
- private String _required;
- private String _externalRequired;
+ private String externalRequired;
- public ConnectRequiredExternallyRequiredEdgeFilter(String aClient, String aRequired,
- String aExternalRequired) {
- _client = aClient;
- _required = aRequired;
- _externalRequired = aExternalRequired;
- if ( _client == null ) {
- throw new IllegalArgumentException("Client component must be specified");
+ /**
+ * Creates a new ConnectRequiredExternallyRequiredEdgeFilter object.
+ *
+ */
+ public ConnectRequiredExternallyRequiredEdgeFilter(String aClient,
+ String aRequired, String aExternalRequired) {
+ client = aClient;
+ required = aRequired;
+ externalRequired = aExternalRequired;
+
+ if (client == null) {
+ throw new IllegalArgumentException(
+ "Client component must be specified");
}
- if ( _required == null ) {
- throw new IllegalArgumentException("Required interface must be specified");
+
+ if (required == null) {
+ throw new IllegalArgumentException(
+ "Required interface must be specified");
}
- if ( _externalRequired == null ) {
- throw new IllegalArgumentException("External required interface must be specified");
+
+ if (externalRequired == null) {
+ throw new IllegalArgumentException(
+ "External required interface must be specified");
}
}
@Override
public boolean isViolated(Edge aEdge) {
- if (aEdge.getFrom() instanceof RequiredInterfaceNode
- && aEdge.getTo() instanceof ExternalRequiredInterfaceNode) {
+ if (aEdge.getFrom() instanceof RequiredInterfaceNode &&
+ aEdge.getTo() instanceof ExternalRequiredInterfaceNode) {
return isViolated((RequiredInterfaceNode) aEdge.getFrom(),
- (ExternalRequiredInterfaceNode) aEdge.getTo());
+ (ExternalRequiredInterfaceNode) aEdge.getTo());
}
+
return false;
}
private boolean isViolated(RequiredInterfaceNode aFrom,
- ExternalRequiredInterfaceNode aTo) {
- if ( !aFrom.getComponent().getName().equals(_client)) {
- return false; // wrong component.
+ ExternalRequiredInterfaceNode aTo) {
+ if (!aFrom.getComponent().getName().equals(client)) {
+ return false; // wrong component.
}
- if ( !(_required == null || aFrom.getRequired().getName().equals(_required))) {
+
+ if (!((required == null) || aFrom.getRequired().getName().equals(
+ required))) {
return false; // wrong interface
}
- if ( !aTo.getRequired().getName().equals(_externalRequired)) {
- return true; // wrong externally required interface.
+
+ if (!aTo.getRequired().getName().equals(externalRequired)) {
+ return true; // wrong externally required interface.
}
-
- return false;
+
+ return false;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
import org.wamblee.system.graph.Edge;
* container.
*
* @author Erik Brakkee
- *
*/
public class ConnectRequiredProvidedEdgeFilter implements EdgeFilter {
+ private String client;
+
+ private String required;
+
+ private String server;
- private String _client;
- private String _required;
- private String _server;
- private String _provided;
+ private String provided;
+ /**
+ * Creates a new ConnectRequiredProvidedEdgeFilter object.
+ *
+ */
public ConnectRequiredProvidedEdgeFilter(String aClient, String aRequired,
- String aServer, String aProvided) {
- _client = aClient;
- _required = aRequired;
- _server = aServer;
- _provided = aProvided;
- if ( _client == null ) {
- throw new IllegalArgumentException("Client component must be specified");
+ String aServer, String aProvided) {
+ client = aClient;
+ required = aRequired;
+ server = aServer;
+ provided = aProvided;
+
+ if (client == null) {
+ throw new IllegalArgumentException(
+ "Client component must be specified");
}
}
@Override
public boolean isViolated(Edge aEdge) {
- if (aEdge.getFrom() instanceof RequiredInterfaceNode
- && aEdge.getTo() instanceof ProvidedInterfaceNode) {
+ if (aEdge.getFrom() instanceof RequiredInterfaceNode &&
+ aEdge.getTo() instanceof ProvidedInterfaceNode) {
return isViolated((RequiredInterfaceNode) aEdge.getFrom(),
- (ProvidedInterfaceNode) aEdge.getTo());
+ (ProvidedInterfaceNode) aEdge.getTo());
}
+
return false;
}
private boolean isViolated(RequiredInterfaceNode aFrom,
- ProvidedInterfaceNode aTo) {
- if (_client.equals(aFrom.getComponent().getName())
- && (_required == null || _required.equals(aFrom.getRequired()
- .getName()))) {
+ ProvidedInterfaceNode aTo) {
+ if (client.equals(aFrom.getComponent().getName()) &&
+ ((required == null) || required.equals(aFrom.getRequired()
+ .getName()))) {
// From part matches.
- if ( _server == null ) {
+ if (server == null) {
return true; // all connections are eliminated
}
- if (_server.equals(aTo.getComponent().getName())
- && (_provided == null || _provided.equals(aTo.getProvided()
- .getName()))) {
+
+ if (server.equals(aTo.getComponent().getName()) &&
+ ((provided == null) || provided.equals(aTo.getProvided()
+ .getName()))) {
// to part matches also
return false;
- }
- else {
+ } else {
// From matches and to doesn't so edgefilter is violated.
- return true;
+ return true;
}
} else {
// From part does not match, restriction does not apply.
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.graph.Node;
/**
- * Represents an external provided interface of a container.
+ * Represents an external provided interface of a container.
+ *
* @author Erik Brakkee
- *
*/
public class ExternalProvidedInterfaceNode implements Node {
+ private Component component;
+
+ private ProvidedInterface provided;
- private Component _component;
- private ProvidedInterface _provided;
-
- public ExternalProvidedInterfaceNode(Component aComponent, ProvidedInterface aProvided) {
- _component = aComponent;
- _provided = aProvided;
+ /**
+ * Creates a new ExternalProvidedInterfaceNode object.
+ *
+ */
+ public ExternalProvidedInterfaceNode(Component aComponent,
+ ProvidedInterface aProvided) {
+ component = aComponent;
+ provided = aProvided;
}
-
+
@Override
public String getName() {
- return _provided.getName();
+ return provided.getName();
}
-
+
public Component getComponent() {
- return _component;
+ return component;
}
-
+
public ProvidedInterface getProvided() {
- return _provided;
+ return provided;
}
-
+
@Override
public String toString() {
- return _component.getQualifiedName() + ":" + _provided;
+ return component.getQualifiedName() + ":" + provided;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.graph.Node;
/**
- * Represents an externally required interface of a container.
+ * Represents an externally required interface of a container.
+ *
* @author Erik Brakkee
- *
*/
public class ExternalRequiredInterfaceNode implements Node {
-
- private Component _component;
- private RequiredInterface _required;
+ private Component component;
+
+ private RequiredInterface required;
- public ExternalRequiredInterfaceNode(Component aComponent, RequiredInterface aRequired) {
- _component = aComponent;
- _required = aRequired;
+ /**
+ * Creates a new ExternalRequiredInterfaceNode object.
+ *
+ */
+ public ExternalRequiredInterfaceNode(Component aComponent,
+ RequiredInterface aRequired) {
+ component = aComponent;
+ required = aRequired;
}
-
+
@Override
public String getName() {
- return _required.getName();
+ return required.getName();
}
-
+
public Component getComponent() {
- return _component;
+ return component;
}
-
+
public RequiredInterface getRequired() {
- return _required;
+ return required;
}
-
+
@Override
public String toString() {
- return _component.getQualifiedName() + ":" + _required;
+ return component.getQualifiedName() + ":" + required;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
import org.wamblee.system.core.ProvidedInterface;
/**
* Visitor that creates links between required and provided interfaces as
- * described by the edges in the graph.
- *
- * Specically it links together (1) required and provided interfaces of internal component
- * of a container and (2) the providers of externally required interfaces and internal required
- * interfaces.
+ * described by the edges in the graph. Specically it links together (1)
+ * required and provided interfaces of internal component of a container and (2)
+ * the providers of externally required interfaces and internal required
+ * interfaces.
*
* @author Erik Brakkee
- *
*/
public class LinkVisitor implements Visitor {
-
@Override
public void visitEdge(Edge aEdge) {
Node from = aEdge.getFrom();
Node to = aEdge.getTo();
+
if (from instanceof RequiredInterfaceNode) {
RequiredInterfaceNode required = (RequiredInterfaceNode) from;
- if (to instanceof ProvidedInterfaceNode) {
+ if (to instanceof ProvidedInterfaceNode) {
ProvidedInterfaceNode provided = (ProvidedInterfaceNode) to;
required.getRequired().setProvider(provided.getProvided());
-
} else if (to instanceof ExternalRequiredInterfaceNode) {
ExternalRequiredInterfaceNode external = (ExternalRequiredInterfaceNode) to;
ProvidedInterface provider = external.getRequired()
- .getProvider();
- if (provider == null && !required.getRequired().isOptional()) {
- throw new SystemAssemblyException("Mandatory interface '"
- + from + "' is not provided.");
+ .getProvider();
+
+ if ((provider == null) && !required.getRequired().isOptional()) {
+ throw new SystemAssemblyException("Mandatory interface '" +
+ from + "' is not provided.");
}
- if ( provider != null ) {
+
+ if (provider != null) {
required.getRequired().setProvider(provider);
}
}
public void visitNode(Node aNode) {
// Empty.
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.graph.Node;
/**
- * Provided interface node.
+ * Provided interface node.
+ *
* @author Erik Brakkee
*/
public class ProvidedInterfaceNode implements Node {
-
- private Component _component;
- private ProvidedInterface _provided;
-
- public ProvidedInterfaceNode(Component aComponent, ProvidedInterface aProvided) {
- _component = aComponent;
- _provided = aProvided;
+ private Component component;
+
+ private ProvidedInterface provided;
+
+ /**
+ * Creates a new ProvidedInterfaceNode object.
+ *
+ */
+ public ProvidedInterfaceNode(Component aComponent,
+ ProvidedInterface aProvided) {
+ component = aComponent;
+ provided = aProvided;
}
@Override
public String getName() {
- return _component.getQualifiedName() + ":" + _provided.getName();
+ return component.getQualifiedName() + ":" + provided.getName();
}
public ProvidedInterface getProvided() {
- return _provided;
+ return provided;
}
-
+
public Component getComponent() {
- return _component;
+ return component;
}
-
+
@Override
public String toString() {
- return _component.getQualifiedName() + ":" + _provided;
+ return component.getQualifiedName() + ":" + provided;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.graph.Node;
/**
- * Required interface node.
+ * Required interface node.
+ *
* @author Erik Brakkee
- *
*/
public class RequiredInterfaceNode implements Node {
-
- private Component _component;
- private RequiredInterface _required;
-
- public RequiredInterfaceNode(Component aComponent, RequiredInterface aRequired) {
- _component = aComponent;
- _required = aRequired;
+ private Component component;
+
+ private RequiredInterface required;
+
+ /**
+ * Creates a new RequiredInterfaceNode object.
+ *
+ */
+ public RequiredInterfaceNode(Component aComponent,
+ RequiredInterface aRequired) {
+ component = aComponent;
+ required = aRequired;
}
@Override
public String getName() {
- return _component.getQualifiedName() + ":" + _required.getName();
+ return component.getQualifiedName() + ":" + required.getName();
}
public RequiredInterface getRequired() {
- return _required;
+ return required;
}
-
+
public Component getComponent() {
- return _component;
+ return component;
}
-
+
@Override
public String toString() {
- return _component.getQualifiedName() + ":" + _required;
+ return component.getQualifiedName() + ":" + required;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
-import java.util.ArrayList;
-import java.util.List;
-
import org.wamblee.system.graph.DefaultEdge;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.EdgeFactory;
import org.wamblee.system.graph.Node;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Factory that creates edges between required and provided interfaces.
- * Speciflcally it creates:
+ * Speciflcally it creates:
* <ul>
- * <li> Edges between provided and required interfaces of a container. </li>
- * <li> Edges between required and externally required interfaces </li>
- * <li> Edges between externally provided and provided interfaces.
+ * <li>Edges between provided and required interfaces of a container.</li>
+ * <li>Edges between required and externally required interfaces</li>
+ * <li>Edges between externally provided and provided interfaces.
* </ul>
*
* @author Erik Brakkee
- *
*/
public class RequiredProvidedEdgeFactory implements EdgeFactory {
-
+ /**
+ * Creates a new RequiredProvidedEdgeFactory object.
+ */
public RequiredProvidedEdgeFactory() {
// Empty.
}
@Override
public List<Edge> create(Node aFrom, Node aTo) {
List<Edge> result = new ArrayList<Edge>();
+
if (aFrom instanceof RequiredInterfaceNode) {
RequiredInterfaceNode required = (RequiredInterfaceNode) aFrom;
+
if (aTo instanceof ProvidedInterfaceNode) {
-
ProvidedInterfaceNode provided = (ProvidedInterfaceNode) aTo;
+
if (required.getRequired()
- .implementedBy(provided.getProvided())) {
+ .implementedBy(provided.getProvided())) {
result.add(new DefaultEdge(required, provided));
}
} else if (aTo instanceof ExternalRequiredInterfaceNode) {
ExternalRequiredInterfaceNode external = (ExternalRequiredInterfaceNode) aTo;
- if ( external.getRequired().covers(required.getRequired())) {
+
+ if (external.getRequired().covers(required.getRequired())) {
result.add(new DefaultEdge(required, external));
}
}
- } else if ( aFrom instanceof ProvidedInterfaceNode) {
- ProvidedInterfaceNode provided = (ProvidedInterfaceNode)aFrom;
- if ( aTo instanceof ExternalProvidedInterfaceNode) {
- ExternalProvidedInterfaceNode external = (ExternalProvidedInterfaceNode)aTo;
- if (provided.getProvided().covers(external.getProvided())) {
+ } else if (aFrom instanceof ProvidedInterfaceNode) {
+ ProvidedInterfaceNode provided = (ProvidedInterfaceNode) aFrom;
+
+ if (aTo instanceof ExternalProvidedInterfaceNode) {
+ ExternalProvidedInterfaceNode external = (ExternalProvidedInterfaceNode) aTo;
+
+ if (provided.getProvided().covers(external.getProvided())) {
result.add(new DefaultEdge(external, provided));
}
}
}
+
return result;
}
-
}
-/**
- * <h1>Graph component package </h1>
+/*
+ * Copyright 2005-2010 the original author or authors.
*
- * The graph component package provides the representation of a number of
- * components {@link Component}
- * their required and provided interfaces ({@link RequiredInterface} and
- * {@link ProvidedInterface}), and how these are connected together.
+ * Licensed 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
*
- * This package provides the bridge between the component model and the
- * representation of the components and their connections in a graph.
- * The component package provides various algorithms, filters, and
- * validations that are required for the implementation of a container.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * The main abstractions are:
- * <ul>
- * <li> {@link ComponentGraph}: A graph of components. This provides the logic
- * for creating a graph based on components. </li>
- * <li> {@link ComponentNode}: A node representing a component. </li>
- * <li> {@link RequiredInterfaceNode}: A node representing a required interface of a component. </li>
- * <li> {@link ProvidedInterfaceNode}: A node repesenting a provided interface of a component. </li>
- * <li> {@link ExternalRequiredInterfaceNode}: A node representing a required interface of a container </li>
- * <li> {@link ExternalProvidedInterfaceNode}: A node representing a provided interface of a container </li>
- * </ul>
- *
- */
+ * 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.wamblee.system.graph.component;
import org.wamblee.system.core.Component;
-/**
- * <h1>Graph package</h1>
+/*
+ * Copyright 2005-2010 the original author or authors.
*
- * The graph package provides a general very simple abstraction of a graph.
- * It was developed for the IOC container to represent dependences between
- * components through their required and provided interfaces.
+ * Licensed 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
*
- * The graph package supports a number of simple graph traversal operations, graph
- * extension operations, and a visitor pattern.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * The main abstractions are:
- * <ul>
- * <li> {@link Graph}: The graph itself. </li>
- * <li> {@link Node}: A node of a graph. </li>
- * <li> {@link Edge}: An edge of a graph> </li>
- * <li> {@link Visitor}: A visitor for implementing various operations on a graph. </li>
- * <li> {@link EdgeFactory}: For extending the graph with new edges </li>
- * </ul>
- */
-package org.wamblee.system.graph;
\ No newline at end of file
+ * 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.wamblee.system.graph;
+
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+import junit.framework.TestCase;
+
import org.wamblee.system.core.DefaultScope;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.Scope;
-import org.wamblee.test.EventTracker;
-import junit.framework.TestCase;
+import org.wamblee.test.EventTracker;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class AdapterTestCase extends TestCase {
-
- protected Scope _scope;
- static EventTracker<String> EVENT_TRACKER;
+ private static EventTracker<String> EVENT_TRACKER;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- EVENT_TRACKER = new EventTracker<String>();
- _scope = new DefaultScope(new ProvidedInterface[0]);
- }
+ private Scope scope;
+ protected Scope getScope() {
+ return scope;
+ }
+
+ public static EventTracker<String> getEventTracker() {
+ return EVENT_TRACKER;
+ }
+
+ private static void setEventTracker(EventTracker<String> aTracker) {
+ EVENT_TRACKER = aTracker;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setEventTracker(new EventTracker<String>());
+ scope = new DefaultScope(new ProvidedInterface[0]);
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+
import org.wamblee.test.AssertionUtils;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ClassAdapterTest extends AdapterTestCase {
+ public void testSimpleConstructorInjection() {
+ ClassConfiguration x1Config = new ClassConfiguration(X1.class);
+ x1Config.getObjectConfig().getSetterConfig().initAllSetters();
+ x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
-
- public void testSimpleConstructorInjection() {
- ClassConfiguration x1Config = new ClassConfiguration(X1.class);
- x1Config.getObjectConfig().getSetterConfig().initAllSetters();
- x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
ClassConfiguration x4Config = new ClassConfiguration(X4.class);
x4Config.getObjectConfig().getSetterConfig().initAllSetters();
-
+
ClassAdapter x1Adapter = new ClassAdapter("x1", x1Config);
ClassAdapter x4Adapter = new ClassAdapter("x4", x4Config);
-
- Container container = new Container("top", new Component[] {
- x1Adapter, x4Adapter
- }, new ProvidedInterface[0], new RequiredInterface[0]);
-
+
+ Container container = new Container("top", new Component[] { x1Adapter,
+ x4Adapter }, new ProvidedInterface[0], new RequiredInterface[0]);
+
Scope scope = container.start();
AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)" },
- EVENT_TRACKER.getEvents(Thread.currentThread()).toArray());
-
+ getEventTracker().getEvents(Thread.currentThread()).toArray());
+
Object obj1 = scope.getRuntime(x1Adapter);
- assertTrue(obj1 instanceof X1);
+ assertTrue(obj1 instanceof X1);
+
Object obj4 = scope.getRuntime(x4Adapter);
assertTrue(obj4 instanceof X4);
-
+
X1 x1 = (X1) obj1;
X4 x4 = (X4) obj4;
-
+
assertSame(x1, x4.getX1());
- }
-
- public void testConstructorAndSetterInjection() {
- ClassConfiguration x1Config = new ClassConfiguration(X1.class);
- x1Config.getObjectConfig().getSetterConfig().initAllSetters();
+ }
+
+ public void testConstructorAndSetterInjection() {
+ ClassConfiguration x1Config = new ClassConfiguration(X1.class);
+ x1Config.getObjectConfig().getSetterConfig().initAllSetters();
x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
+
ClassConfiguration x4Config = new ClassConfiguration(X4.class);
x4Config.getObjectConfig().getSetterConfig().initAllSetters();
+
ClassConfiguration x8Config = new ClassConfiguration(X8.class);
x8Config.getObjectConfig().getSetterConfig().initAllSetters();
-
+
ClassAdapter x1Adapter = new ClassAdapter("x1", x1Config);
ClassAdapter x4Adapter = new ClassAdapter("x4", x4Config);
ClassAdapter x8Adapter = new ClassAdapter("x8", x8Config);
-
- Container container = new Container("top", new Component[] {
- x1Adapter, x4Adapter, x8Adapter
- }, new ProvidedInterface[0], new RequiredInterface[0]);
-
+
+ Container container = new Container("top", new Component[] { x1Adapter,
+ x4Adapter, x8Adapter }, new ProvidedInterface[0],
+ new RequiredInterface[0]);
+
Scope scope = container.start();
- AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)", "x8(x1)", "x8.setX4(x4)" },
- EVENT_TRACKER.getEvents(Thread.currentThread()).toArray());
-
+ AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)",
+ "x8(x1)", "x8.setX4(x4)" }, getEventTracker().getEvents(
+ Thread.currentThread()).toArray());
+
Object obj1 = scope.getRuntime(x1Adapter);
- assertTrue(obj1 instanceof X1);
+ assertTrue(obj1 instanceof X1);
+
Object obj4 = scope.getRuntime(x4Adapter);
assertTrue(obj4 instanceof X4);
- Object obj8 = scope.getRuntime(x8Adapter);
-
+
+ Object obj8 = scope.getRuntime(x8Adapter);
+
X1 x1 = (X1) obj1;
X4 x4 = (X4) obj4;
- X8 x8 = (X8) obj8;
-
+ X8 x8 = (X8) obj8;
+
assertSame(x4, x8.getX4());
assertSame(x1, x8.getX1());
- }
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import java.util.Collections;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.RequiredInterfaceComparator;
+import org.wamblee.system.core.Scope;
import org.wamblee.test.AssertionUtils;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ClassConfigurationTest extends AdapterTestCase {
-
public void testConstructorConfig() {
ClassConfiguration classConfig = new ClassConfiguration(X1.class);
- ConstructorConfiguration config = classConfig.getConstructorConfig()
- .greedy();
-
ProvidedInterface provided = new DefaultProvidedInterface("arg",
- String.class);
+ String.class);
List<RequiredInterface> required = classConfig.getRequiredInterfaces();
assertEquals(1, required.size());
required.get(0).setProvider(provided);
- _scope.publishInterface(provided, "hello");
- classConfig.create(_scope);
+ getScope().publishInterface(provided, "hello");
+ classConfig.create(getScope());
AssertionUtils.assertEquals(new String[] { "x1(hello)" },
- AdapterTestCase.EVENT_TRACKER.getEvents(Thread.currentThread())
- .toArray());
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
}
public void testConstructorConfigWithSetters() {
ClassConfiguration classConfig = new ClassConfiguration(X7.class);
classConfig.getConstructorConfig().select(Boolean.class);
- classConfig.getObjectConfig().getSetterConfig().initAllSetters().values("setPort").setValue(0, 10);
-
- ProvidedInterface providedBoolean = new DefaultProvidedInterface("boolean",
- Boolean.class);
- ProvidedInterface providedHost = new DefaultProvidedInterface("host", String.class);
+ classConfig.getObjectConfig().getSetterConfig().initAllSetters()
+ .values("setPort").setValue(0, 10);
+
+ ProvidedInterface providedBoolean = new DefaultProvidedInterface(
+ "boolean", Boolean.class);
+ ProvidedInterface providedHost = new DefaultProvidedInterface("host",
+ String.class);
List<RequiredInterface> required = classConfig.getRequiredInterfaces();
Collections.sort(required, new RequiredInterfaceComparator());
required.get(0).setProvider(providedBoolean);
required.get(1).setProvider(providedHost);
- _scope.publishInterface(providedBoolean, true);
- _scope.publishInterface(providedHost, "host.name.org");
-
- Object obj = classConfig.create(_scope);
+ Scope scope = getScope();
+ scope.publishInterface(providedBoolean, true);
+ scope.publishInterface(providedHost, "host.name.org");
+
+ Object obj = classConfig.create(scope);
assertTrue(obj instanceof X7);
- X7 x7 = (X7)obj;
+
+ X7 x7 = (X7) obj;
assertNotNull(x7.getBoolean());
assertTrue(x7.getBoolean());
assertNull(x7.getHost());
assertNull(x7.getPort());
- classConfig.inject(_scope, obj);
-
+ classConfig.inject(scope, obj);
+
assertEquals("host.name.org", x7.getHost());
assertEquals(10, x7.getPort().intValue());
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import java.util.List;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
+import org.wamblee.system.core.Scope;
import org.wamblee.system.core.SystemAssemblyException;
import org.wamblee.test.AssertionUtils;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ConstructorConfigurationTest extends AdapterTestCase {
-
- public void testGreedyUnique() {
- ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
- .greedy();
- ProvidedInterface provided = new DefaultProvidedInterface("arg",
- String.class);
- List<RequiredInterface> required = config.getRequiredInterfaces();
-
- assertEquals(1, required.size());
- assertFalse(required.get(0).isOptional());
-
- required.get(0).setProvider(provided);
-
- _scope.publishInterface(provided, "hello");
- config.create(_scope);
-
- AssertionUtils.assertEquals(new String[] { "x1(hello)" }, AdapterTestCase.EVENT_TRACKER
- .getEvents(Thread.currentThread()).toArray());
- }
-
- public void testGreedyNonUnique() {
- try {
- ConstructorConfiguration config = new ConstructorConfiguration(
- X2.class).greedy();
- } catch (SystemAssemblyException e) {
- // e.printStackTrace();
- return;
- }
- fail();
- }
-
- public void testSpecificConstructor() {
- ConstructorConfiguration config = new ConstructorConfiguration(X2.class)
- .select(String.class);
- ProvidedInterface provided = new DefaultProvidedInterface("arg",
- String.class);
- List<RequiredInterface> required = config.getRequiredInterfaces();
-
- assertEquals(1, required.size());
- required.get(0).setProvider(provided);
-
- _scope.publishInterface(provided, "hello");
- config.create(_scope);
-
- AssertionUtils.assertEquals(new String[] { "x2(hello)" }, AdapterTestCase.EVENT_TRACKER
- .getEvents(Thread.currentThread()).toArray());
- }
-
- public void testSetValue() {
- ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
- .greedy();
- config.getParameters().setValue(0, "bla");
-
- config.create(_scope);
-
- AssertionUtils.assertEquals(new String[] { "x1(bla)" }, AdapterTestCase.EVENT_TRACKER
- .getEvents(Thread.currentThread()).toArray());
- }
-
- public void testOptionalValueProvided() {
- ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
- .greedy();
- config.getParameters().setOptional(0);
- ProvidedInterface provided = new DefaultProvidedInterface("arg",
- String.class);
- List<RequiredInterface> required = config.getRequiredInterfaces();
-
- assertEquals(1, required.size());
- required.get(0).setProvider(provided);
-
- _scope.publishInterface(provided, "hello");
- config.create(_scope);
-
- AssertionUtils.assertEquals(new String[] { "x1(hello)" }, AdapterTestCase.EVENT_TRACKER
- .getEvents(Thread.currentThread()).toArray());
- }
-
- public void testOptionalValueMissing() {
- ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
- .greedy();
- config.getParameters().setOptional(0);
- assertTrue(config.getRequiredInterfaces().get(0).isOptional());
-
- config.create(_scope);
-
- AssertionUtils.assertEquals(new String[] { "x1(null)" }, AdapterTestCase.EVENT_TRACKER
- .getEvents(Thread.currentThread()).toArray());
- }
-
- public void testIgnoredNonPublic() {
- ConstructorConfiguration config = new ConstructorConfiguration(X3.class)
- .greedy();
- List<RequiredInterface> required = config.getRequiredInterfaces();
- assertEquals(0, config.getParameters().getTypes().length);
- }
-
- public void testNonPublicConstructor() {
- ConstructorConfiguration config = new ConstructorConfiguration(X3.class)
- .setNonPublic(true).greedy();
- ProvidedInterface provided = new DefaultProvidedInterface("arg",
- String.class);
- List<RequiredInterface> required = config.getRequiredInterfaces();
-
- assertEquals(1, required.size());
- assertFalse(required.get(0).isOptional());
-
- required.get(0).setProvider(provided);
-
- _scope.publishInterface(provided, "hello");
- config.create(_scope);
-
- AssertionUtils.assertEquals(new String[] { "x3(hello)" }, AdapterTestCase.EVENT_TRACKER
- .getEvents(Thread.currentThread()).toArray());
- }
+ public void testGreedyUnique() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
+ .greedy();
+ ProvidedInterface provided = new DefaultProvidedInterface("arg",
+ String.class);
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+
+ assertEquals(1, required.size());
+ assertFalse(required.get(0).isOptional());
+
+ required.get(0).setProvider(provided);
+
+ Scope scope = getScope();
+ scope.publishInterface(provided, "hello");
+ config.create(scope);
+
+ AssertionUtils.assertEquals(new String[] { "x1(hello)" },
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+ }
+
+ public void testGreedyNonUnique() {
+ try {
+ ConstructorConfiguration config = new ConstructorConfiguration(
+ X2.class).greedy();
+ ignoredVariable(config);
+ } catch (SystemAssemblyException e) {
+ // e.printStackTrace();
+ return;
+ }
+
+ fail();
+ }
+
+ private static void ignoredVariable(Object aObject) {
+ // for findbugs.
+ }
+
+ public void testSpecificConstructor() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X2.class)
+ .select(String.class);
+ ProvidedInterface provided = new DefaultProvidedInterface("arg",
+ String.class);
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+
+ assertEquals(1, required.size());
+ required.get(0).setProvider(provided);
+
+ Scope scope = getScope();
+ scope.publishInterface(provided, "hello");
+ config.create(scope);
+
+ AssertionUtils.assertEquals(new String[] { "x2(hello)" },
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+ }
+
+ public void testSetValue() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
+ .greedy();
+ config.getParameters().setValue(0, "bla");
+
+ Scope scope = getScope();
+ config.create(scope);
+
+ AssertionUtils.assertEquals(new String[] { "x1(bla)" },
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+ }
+
+ public void testOptionalValueProvided() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
+ .greedy();
+ config.getParameters().setOptional(0);
+
+ ProvidedInterface provided = new DefaultProvidedInterface("arg",
+ String.class);
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+
+ assertEquals(1, required.size());
+ required.get(0).setProvider(provided);
+
+ Scope scope = getScope();
+ scope.publishInterface(provided, "hello");
+ config.create(scope);
+
+ AssertionUtils.assertEquals(new String[] { "x1(hello)" },
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+ }
+
+ public void testOptionalValueMissing() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X1.class)
+ .greedy();
+ config.getParameters().setOptional(0);
+ assertTrue(config.getRequiredInterfaces().get(0).isOptional());
+
+ Scope scope = getScope();
+ config.create(scope);
+
+ AssertionUtils.assertEquals(new String[] { "x1(null)" },
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+ }
+
+ public void testIgnoredNonPublic() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X3.class)
+ .greedy();
+ assertEquals(0, config.getParameters().getTypes().length);
+ }
+
+ public void testNonPublicConstructor() {
+ ConstructorConfiguration config = new ConstructorConfiguration(X3.class)
+ .setNonPublic(true).greedy();
+ ProvidedInterface provided = new DefaultProvidedInterface("arg",
+ String.class);
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+
+ assertEquals(1, required.size());
+ assertFalse(required.get(0).isOptional());
+
+ required.get(0).setProvider(provided);
+
+ Scope scope = getScope();
+ scope.publishInterface(provided, "hello");
+ config.create(scope);
+
+ AssertionUtils.assertEquals(new String[] { "x3(hello)" },
+ AdapterTestCase.getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import org.wamblee.system.core.Scope;
+
import org.wamblee.test.AssertionUtils;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultContainerTest extends AdapterTestCase {
-
public void testConstructorInjection() {
ClassConfiguration x1Config = new ClassConfiguration(X1.class);
x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
x1Config.getObjectConfig().getSetterConfig().initAllSetters();
-
+
ClassConfiguration x4Config = new ClassConfiguration(X4.class);
x4Config.getObjectConfig().getSetterConfig().initAllSetters();
DefaultContainer container = new DefaultContainer("top").addComponent(
- "x1", x1Config).addComponent("x4", x4Config);
+ "x1", x1Config).addComponent("x4", x4Config);
Scope scope = container.start();
AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)" },
- EVENT_TRACKER.getEvents(Thread.currentThread()).toArray());
+ getEventTracker().getEvents(Thread.currentThread()).toArray());
Object obj = scope.getRuntime("x1");
assertTrue(obj instanceof X1);
obj = scope.getRuntime("x4");
assertTrue(obj instanceof X4);
}
-
+
public void testConstructorInjectionAndSetterInjection() {
ClassConfiguration x1Config = new ClassConfiguration(X1.class);
x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
x1Config.getObjectConfig().getSetterConfig().initAllSetters();
-
- X8 x8 = new X8(null);
- EVENT_TRACKER.clear();
+
+ X8 x8 = new X8(null);
+ getEventTracker().clear();
ClassConfiguration x4Config = new ClassConfiguration(X4.class);
x4Config.getObjectConfig().getSetterConfig().initAllSetters();
-
+
ObjectConfiguration x8Config = new ObjectConfiguration(X8.class);
x8Config.getSetterConfig().initAllSetters();
-
+
DefaultContainer container = new DefaultContainer("top").addComponent(
- "x1", x1Config).addComponent("x4", x4Config).addComponent("x8", x8, x8Config);
+ "x1", x1Config).addComponent("x4", x4Config).addComponent("x8", x8,
+ x8Config);
Scope scope = container.start();
AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)",
- "x8.setX4(x4)"},
- EVENT_TRACKER.getEvents(Thread.currentThread()).toArray());
+ "x8.setX4(x4)" }, getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
Object obj1 = scope.getRuntime("x1");
assertTrue(obj1 instanceof X1);
+
Object obj4 = scope.getRuntime("x4");
assertTrue(obj4 instanceof X4);
+
Object obj8 = scope.getRuntime("x8");
assertSame(x8, obj8);
assertSame(obj4, x8.getX4());
}
-
- public void testWrongObjectType() {
+
+ public void testWrongObjectType() {
final DefaultContainer container = new DefaultContainer("top");
AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
@Override
public void run() throws Exception {
- container.addComponent("x", "y", new ObjectConfiguration(Integer.class));
+ container.addComponent("x", "y", new ObjectConfiguration(
+ Integer.class));
}
}, IllegalArgumentException.class);
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
-import java.util.Collections;
-import java.util.List;
-
import org.wamblee.system.container.Container;
import org.wamblee.system.core.Component;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.RequiredInterfaceComparator;
import org.wamblee.system.core.Scope;
+
import org.wamblee.test.AssertionUtils;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ObjectAdapterTest extends AdapterTestCase {
+ public void testSetterInjection() {
+ ClassConfiguration x1Config = new ClassConfiguration(X1.class);
+ x1Config.getObjectConfig().getSetterConfig().initAllSetters();
+ x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
- public void testSetterInjection() {
-
- ClassConfiguration x1Config = new ClassConfiguration(X1.class);
- x1Config.getObjectConfig().getSetterConfig().initAllSetters();
- x1Config.getConstructorConfig().getParameters().setValue(0, "hello");
-
ClassConfiguration x4Config = new ClassConfiguration(X4.class);
x4Config.getObjectConfig().getSetterConfig().initAllSetters();
+
ObjectConfiguration x8Config = new ObjectConfiguration(X8.class);
x8Config.getSetterConfig().initAllSetters();
-
- X1 x1 = new X1();
+
+ X1 x1 = new X1();
X8 x8 = new X8(x1);
-
+
ClassAdapter x1Adapter = new ClassAdapter("x1", x1Config);
ClassAdapter x4Adapter = new ClassAdapter("x4", x4Config);
ObjectAdapter x8Adapter = new ObjectAdapter("x8", x8, x8Config);
-
- Container container = new Container("top", new Component[] {
- x1Adapter, x4Adapter, x8Adapter
- }, new ProvidedInterface[0], new RequiredInterface[0]);
-
- EVENT_TRACKER.clear();
+
+ Container container = new Container("top", new Component[] { x1Adapter,
+ x4Adapter, x8Adapter }, new ProvidedInterface[0],
+ new RequiredInterface[0]);
+
+ getEventTracker().clear();
+
Scope scope = container.start();
- AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)", "x8.setX4(x4)" },
- EVENT_TRACKER.getEvents(Thread.currentThread()).toArray());
-
+ AssertionUtils.assertEquals(new String[] { "x1(hello)", "x4(x1)",
+ "x8.setX4(x4)" }, getEventTracker().getEvents(Thread.currentThread())
+ .toArray());
+
Object obj1 = scope.getRuntime(x1Adapter);
- assertTrue(obj1 instanceof X1);
+ assertTrue(obj1 instanceof X1);
+
Object obj4 = scope.getRuntime(x4Adapter);
assertTrue(obj4 instanceof X4);
+
Object obj8 = scope.getRuntime(x8Adapter);
assertSame(x8, obj8);
-
+
X4 x4 = (X4) obj4;
-
-
+
assertSame(x4, x8.getX4());
assertSame(x1, x8.getX1());
- }
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.adapters;
import java.lang.reflect.Method;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.RequiredInterfaceComparator;
+import org.wamblee.system.core.Scope;
import org.wamblee.test.AssertionUtils;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class SetterConfigurationTest extends AdapterTestCase {
+ public void testOneSetter() {
+ SetterConfiguration config = new SetterConfiguration(X5.class);
+ config.initAllSetters();
+
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ assertEquals(1, required.size());
+ assertEquals("setValue.0", required.get(0).getName());
+
+ ProvidedInterface provided = new DefaultProvidedInterface("janse",
+ String.class);
+ required.get(0).setProvider(provided);
+ Scope scope = getScope();
+ scope.publishInterface(provided, "hello");
+
+ X5 obj = new X5();
+ assertNull(obj.getValue());
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getValue());
+ }
+
+ public void testPrivateSetter() {
+ SetterConfiguration config = new SetterConfiguration(X5.class);
+ config.setNonPublic(true);
+ config.initAllSetters();
+
+ List<RequiredInterface> required = new ArrayList<RequiredInterface>(
+ config.getRequiredInterfaces());
+ Collections.sort(required, new Comparator<RequiredInterface>() {
+ @Override
+ public int compare(RequiredInterface aO1, RequiredInterface aO2) {
+ return aO1.getName().compareTo(aO2.getName());
+ }
+ });
+ assertEquals(2, required.size());
+ assertEquals("setValue.0", required.get(0).getName());
+ assertEquals("setXyz.0", required.get(1).getName());
+
+ ProvidedInterface providedString = new DefaultProvidedInterface(
+ "janse", String.class);
+ assertTrue(required.get(0).implementedBy(providedString));
+ required.get(0).setProvider(providedString);
+ Scope scope = getScope();
+ scope.publishInterface(providedString, "hello");
+
+ ProvidedInterface providedInt = new DefaultProvidedInterface("xxx",
+ Integer.class);
+ assertTrue(required.get(1).implementedBy(providedInt));
+ required.get(1).setProvider(providedInt);
+ scope.publishInterface(providedInt, 100);
+
+ X5 obj = new X5();
+ assertNull(obj.getValue());
+ assertNull(obj.getXyz());
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getValue());
+ assertEquals(100, obj.getXyz().intValue());
+ }
+
+ public void testInheritance() {
+ SetterConfiguration config = new SetterConfiguration(X9.class);
+ config.setNonPublic(true);
+ config.initAllSetters();
+
+ List<RequiredInterface> required = new ArrayList<RequiredInterface>(
+ config.getRequiredInterfaces());
+ Collections.sort(required, new Comparator<RequiredInterface>() {
+ @Override
+ public int compare(RequiredInterface aO1, RequiredInterface aO2) {
+ return aO1.getName().compareTo(aO2.getName());
+ }
+ });
+ assertEquals(3, required.size());
+ assertEquals("setFlag.0", required.get(0).getName());
+ assertEquals("setValue.0", required.get(1).getName());
+ assertEquals("setXyz.0", required.get(2).getName());
+
+ ProvidedInterface providedBoolean = new DefaultProvidedInterface(
+ "janse", Boolean.class);
+ assertTrue(required.get(0).implementedBy(providedBoolean));
+ required.get(0).setProvider(providedBoolean);
+ Scope scope = getScope();
+ scope.publishInterface(providedBoolean, true);
+
+ ProvidedInterface providedString = new DefaultProvidedInterface(
+ "janse", String.class);
+ assertTrue(required.get(1).implementedBy(providedString));
+ required.get(1).setProvider(providedString);
+ scope.publishInterface(providedString, "hello");
+
+ ProvidedInterface providedInt = new DefaultProvidedInterface("xxx",
+ Integer.class);
+ assertTrue(required.get(2).implementedBy(providedInt));
+ required.get(2).setProvider(providedInt);
+ scope.publishInterface(providedInt, 100);
+
+ X9 obj = new X9();
+ assertNull(obj.getValue());
+ assertNull(obj.getXyz());
+ assertFalse(obj.isFlag());
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getValue());
+ assertEquals(100, obj.getXyz().intValue());
+ assertTrue(obj.isFlag());
+ }
+
+ public void testMultipleSetters() {
+ SetterConfiguration config = new SetterConfiguration(X6.class)
+ .initAllSetters();
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ Collections.sort(required, new RequiredInterfaceComparator());
+ assertEquals(2, required.size());
+ assertEquals("setHost.0", required.get(0).getName());
+ assertEquals("setPort.0", required.get(1).getName());
+
+ ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
+ String.class);
+ required.get(0).setProvider(provided0);
+ Scope scope = getScope();
+ scope.publishInterface(provided0, "hello");
+
+ ProvidedInterface provided1 = new DefaultProvidedInterface("port",
+ Integer.class);
+ required.get(1).setProvider(provided1);
+ scope.publishInterface(provided1, 10);
+
+ X6 obj = new X6();
+ assertNull(obj.getHost());
+ assertNull(obj.getPort());
+
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getHost());
+ assertEquals(10, obj.getPort().intValue());
+ }
+
+ public void testInvokeWrongType() {
+ final SetterConfiguration config = new SetterConfiguration(X5.class)
+ .initAllSetters();
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ assertEquals(1, required.size());
+ assertEquals("setValue.0", required.get(0).getName());
+
+ ProvidedInterface provided = new DefaultProvidedInterface("janse",
+ String.class);
+ required.get(0).setProvider(provided);
+ final Scope scope = getScope();
+ scope.publishInterface(provided, "hello");
+
+ final X6 obj = new X6();
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ config.inject(scope, obj);
+ }
+ }, IllegalArgumentException.class);
+ }
+
+ public void testSetExplicitValue() {
+ SetterConfiguration config = new SetterConfiguration(X5.class)
+ .initAllSetters();
+ config.values("setValue").setValue(0, "bladibla");
+
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ assertEquals(0, required.size());
+
+ X5 obj = new X5();
+ assertNull(obj.getValue());
+ Scope scope = getScope();
+ config.inject(scope, obj);
+ assertEquals("bladibla", obj.getValue());
+ }
+
+ public void testClear() {
+ SetterConfiguration config = new SetterConfiguration(X6.class);
+ config.clear();
+
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ Collections.sort(required, new RequiredInterfaceComparator());
+ assertEquals(0, required.size());
+
+ X6 obj = new X6();
+ assertNull(obj.getHost());
+ assertNull(obj.getPort());
+
+ Scope scope = getScope();
+ config.inject(scope, obj);
+
+ assertNull(obj.getHost());
+ assertNull(obj.getPort());
+ }
+
+ public void testAddByName() {
+ SetterConfiguration config = new SetterConfiguration(X6.class);
+ config.clear().add("setHost");
+
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ Collections.sort(required, new RequiredInterfaceComparator());
+ assertEquals(1, required.size());
+ assertEquals("setHost.0", required.get(0).getName());
+
+ ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
+ String.class);
+ required.get(0).setProvider(provided0);
+ Scope scope = getScope();
+ scope.publishInterface(provided0, "hello");
+
+ X6 obj = new X6();
+ assertNull(obj.getHost());
+ assertNull(obj.getPort());
+
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getHost());
+ assertNull(obj.getPort());
+ }
+
+ public void testAddByType() {
+ SetterConfiguration config = new SetterConfiguration(X6.class);
+ config.clear().addSetter(String.class);
+
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ Collections.sort(required, new RequiredInterfaceComparator());
+ assertEquals(1, required.size());
+ assertEquals("setHost.0", required.get(0).getName());
+
+ ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
+ String.class);
+ required.get(0).setProvider(provided0);
+ Scope scope = getScope();
+ scope.publishInterface(provided0, "hello");
+
+ X6 obj = new X6();
+ assertNull(obj.getHost());
+ assertNull(obj.getPort());
+
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getHost());
+ assertNull(obj.getPort());
+ }
+
+ public void testAddPrivate() {
+ final SetterConfiguration config = new SetterConfiguration(X5.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ config.add("xyz");
+ }
+ }, IllegalArgumentException.class);
+
+ config.setNonPublic(true);
+ config.clear();
+ config.add("setXyz");
+ assertEquals(1, config.getRequiredInterfaces().size());
+ }
- public void testOneSetter() {
- SetterConfiguration config = new SetterConfiguration(X5.class);
- config.initAllSetters();
- List<RequiredInterface> required = config.getRequiredInterfaces();
- assertEquals(1, required.size());
- assertEquals("setValue.0", required.get(0).getName());
-
- ProvidedInterface provided = new DefaultProvidedInterface("janse",
- String.class);
- required.get(0).setProvider(provided);
- _scope.publishInterface(provided, "hello");
-
- X5 obj = new X5();
- assertNull(obj.getValue());
- config.inject(_scope, obj);
- assertEquals("hello", obj.getValue());
- }
-
- public void testPrivateSetter() {
- SetterConfiguration config = new SetterConfiguration(X5.class);
- config.setNonPublic(true);
- config.initAllSetters();
- List<RequiredInterface> required = new ArrayList<RequiredInterface>(
- config.getRequiredInterfaces());
- Collections.sort(required, new Comparator<RequiredInterface>() {
- @Override
- public int compare(RequiredInterface aO1, RequiredInterface aO2) {
- return aO1.getName().compareTo(aO2.getName());
- }
- });
- assertEquals(2, required.size());
- assertEquals("setValue.0", required.get(0).getName());
- assertEquals("setXyz.0", required.get(1).getName());
-
- ProvidedInterface providedString = new DefaultProvidedInterface(
- "janse", String.class);
- assertTrue(required.get(0).implementedBy(providedString));
- required.get(0).setProvider(providedString);
- _scope.publishInterface(providedString, "hello");
-
- ProvidedInterface providedInt = new DefaultProvidedInterface("xxx",
- Integer.class);
- assertTrue(required.get(1).implementedBy(providedInt));
- required.get(1).setProvider(providedInt);
- _scope.publishInterface(providedInt, 100);
-
- X5 obj = new X5();
- assertNull(obj.getValue());
- assertNull(obj.getXyz());
- config.inject(_scope, obj);
- assertEquals("hello", obj.getValue());
- assertEquals(100, obj.getXyz().intValue());
- }
-
- public void testInheritance() {
- SetterConfiguration config = new SetterConfiguration(X9.class);
- config.setNonPublic(true);
- config.initAllSetters();
- List<RequiredInterface> required = new ArrayList<RequiredInterface>(
- config.getRequiredInterfaces());
- Collections.sort(required, new Comparator<RequiredInterface>() {
- @Override
- public int compare(RequiredInterface aO1, RequiredInterface aO2) {
- return aO1.getName().compareTo(aO2.getName());
- }
- });
- assertEquals(3, required.size());
- assertEquals("setFlag.0", required.get(0).getName());
- assertEquals("setValue.0", required.get(1).getName());
- assertEquals("setXyz.0", required.get(2).getName());
-
- ProvidedInterface providedBoolean = new DefaultProvidedInterface(
- "janse", Boolean.class);
- assertTrue(required.get(0).implementedBy(providedBoolean));
- required.get(0).setProvider(providedBoolean);
- _scope.publishInterface(providedBoolean, true);
-
- ProvidedInterface providedString = new DefaultProvidedInterface(
- "janse", String.class);
- assertTrue(required.get(1).implementedBy(providedString));
- required.get(1).setProvider(providedString);
- _scope.publishInterface(providedString, "hello");
-
- ProvidedInterface providedInt = new DefaultProvidedInterface("xxx",
- Integer.class);
- assertTrue(required.get(2).implementedBy(providedInt));
- required.get(2).setProvider(providedInt);
- _scope.publishInterface(providedInt, 100);
-
- X9 obj = new X9();
- assertNull(obj.getValue());
- assertNull(obj.getXyz());
- assertFalse(obj.isFlag());
- config.inject(_scope, obj);
- assertEquals("hello", obj.getValue());
- assertEquals(100, obj.getXyz().intValue());
- assertTrue(obj.isFlag());
- }
-
- public void testMultipleSetters() {
- SetterConfiguration config = new SetterConfiguration(X6.class).initAllSetters();
- List<RequiredInterface> required = config.getRequiredInterfaces();
- Collections.sort(required, new RequiredInterfaceComparator());
- assertEquals(2, required.size());
- assertEquals("setHost.0", required.get(0).getName());
- assertEquals("setPort.0", required.get(1).getName());
-
- ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
- String.class);
- required.get(0).setProvider(provided0);
- _scope.publishInterface(provided0, "hello");
-
- ProvidedInterface provided1 = new DefaultProvidedInterface("port",
- Integer.class);
- required.get(1).setProvider(provided1);
- _scope.publishInterface(provided1, 10);
-
- X6 obj = new X6();
- assertNull(obj.getHost());
- assertNull(obj.getPort());
-
- config.inject(_scope, obj);
- assertEquals("hello", obj.getHost());
- assertEquals(10, obj.getPort().intValue());
- }
-
- public void testInvokeWrongType() {
- final SetterConfiguration config = new SetterConfiguration(X5.class).initAllSetters();
- List<RequiredInterface> required = config.getRequiredInterfaces();
- assertEquals(1, required.size());
- assertEquals("setValue.0", required.get(0).getName());
-
- ProvidedInterface provided = new DefaultProvidedInterface("janse",
- String.class);
- required.get(0).setProvider(provided);
- _scope.publishInterface(provided, "hello");
-
- final X6 obj = new X6();
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- config.inject(_scope, obj);
- }
- }, IllegalArgumentException.class);
- }
-
- public void testSetExplicitValue() {
- SetterConfiguration config = new SetterConfiguration(X5.class).initAllSetters();
- config.values("setValue").setValue(0, "bladibla");
-
- List<RequiredInterface> required = config.getRequiredInterfaces();
- assertEquals(0, required.size());
-
- X5 obj = new X5();
- assertNull(obj.getValue());
- config.inject(_scope, obj);
- assertEquals("bladibla", obj.getValue());
- }
-
- public void testClear() {
- SetterConfiguration config = new SetterConfiguration(X6.class);
- config.clear();
- List<RequiredInterface> required = config.getRequiredInterfaces();
- Collections.sort(required, new RequiredInterfaceComparator());
- assertEquals(0, required.size());
-
- X6 obj = new X6();
- assertNull(obj.getHost());
- assertNull(obj.getPort());
-
- config.inject(_scope, obj);
-
- assertNull(obj.getHost());
- assertNull(obj.getPort());
- }
-
- public void testAddByName() {
- SetterConfiguration config = new SetterConfiguration(X6.class);
- config.clear().add("setHost");
- List<RequiredInterface> required = config.getRequiredInterfaces();
- Collections.sort(required, new RequiredInterfaceComparator());
- assertEquals(1, required.size());
- assertEquals("setHost.0", required.get(0).getName());
-
- ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
- String.class);
- required.get(0).setProvider(provided0);
- _scope.publishInterface(provided0, "hello");
-
- X6 obj = new X6();
- assertNull(obj.getHost());
- assertNull(obj.getPort());
-
- config.inject(_scope, obj);
- assertEquals("hello", obj.getHost());
- assertNull(obj.getPort());
- }
-
- public void testAddByType() {
- SetterConfiguration config = new SetterConfiguration(X6.class);
- config.clear().addSetter(String.class);
- List<RequiredInterface> required = config.getRequiredInterfaces();
- Collections.sort(required, new RequiredInterfaceComparator());
- assertEquals(1, required.size());
- assertEquals("setHost.0", required.get(0).getName());
-
- ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
- String.class);
- required.get(0).setProvider(provided0);
- _scope.publishInterface(provided0, "hello");
-
- X6 obj = new X6();
- assertNull(obj.getHost());
- assertNull(obj.getPort());
-
- config.inject(_scope, obj);
- assertEquals("hello", obj.getHost());
- assertNull(obj.getPort());
- }
-
- public void testAddPrivate() {
- X5 obj = new X5();
- final SetterConfiguration config = new SetterConfiguration(X5.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- config.add("xyz");
- }
- }, IllegalArgumentException.class);
-
- config.setNonPublic(true);
- config.clear();
- config.add("setXyz");
- assertEquals(1, config.getRequiredInterfaces().size());
- }
-
- public void testAddNonExisting() {
- final SetterConfiguration config = new SetterConfiguration(X6.class);
- config.clear();
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- config.add("bladibla");
- }
- }, IllegalArgumentException.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- config.addSetter(DataSource.class);
- }
- }, IllegalArgumentException.class);
- }
-
- public void testAddByTypeNonUnique() {
- final SetterConfiguration config = new SetterConfiguration(X11.class);
- config.clear();
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- config.addSetter(String.class);
- }
- }, IllegalArgumentException.class);
- }
-
- public void testRemove() {
- SetterConfiguration config = new SetterConfiguration(X6.class).initAllSetters();
- config.remove("setPort");
- List<RequiredInterface> required = config.getRequiredInterfaces();
- Collections.sort(required, new RequiredInterfaceComparator());
- assertEquals(1, required.size());
- assertEquals("setHost.0", required.get(0).getName());
-
- ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
- String.class);
- required.get(0).setProvider(provided0);
- _scope.publishInterface(provided0, "hello");
-
- X6 obj = new X6();
- assertNull(obj.getHost());
- assertNull(obj.getPort());
-
- config.inject(_scope, obj);
- assertEquals("hello", obj.getHost());
- assertNull(obj.getPort());
- }
-
- public void testRemoveByMethodObject() throws NoSuchMethodException {
- SetterConfiguration config = new SetterConfiguration(X6.class).initAllSetters();
+ public void testAddNonExisting() {
+ final SetterConfiguration config = new SetterConfiguration(X6.class);
+ config.clear();
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ config.add("bladibla");
+ }
+ }, IllegalArgumentException.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ config.addSetter(DataSource.class);
+ }
+ }, IllegalArgumentException.class);
+ }
+
+ public void testAddByTypeNonUnique() {
+ final SetterConfiguration config = new SetterConfiguration(X11.class);
+ config.clear();
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ config.addSetter(String.class);
+ }
+ }, IllegalArgumentException.class);
+ }
+
+ public void testRemove() {
+ SetterConfiguration config = new SetterConfiguration(X6.class)
+ .initAllSetters();
+ config.remove("setPort");
+
+ List<RequiredInterface> required = config.getRequiredInterfaces();
+ Collections.sort(required, new RequiredInterfaceComparator());
+ assertEquals(1, required.size());
+ assertEquals("setHost.0", required.get(0).getName());
+
+ ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
+ String.class);
+ required.get(0).setProvider(provided0);
+ Scope scope = getScope();
+ scope.publishInterface(provided0, "hello");
+
+ X6 obj = new X6();
+ assertNull(obj.getHost());
+ assertNull(obj.getPort());
+
+ config.inject(scope, obj);
+ assertEquals("hello", obj.getHost());
+ assertNull(obj.getPort());
+ }
+
+ public void testRemoveByMethodObject() throws NoSuchMethodException {
+ SetterConfiguration config = new SetterConfiguration(X6.class)
+ .initAllSetters();
config.remove(X6.class.getMethod("setPort", Integer.class));
+
List<RequiredInterface> required = config.getRequiredInterfaces();
Collections.sort(required, new RequiredInterfaceComparator());
assertEquals(1, required.size());
assertEquals("setHost.0", required.get(0).getName());
ProvidedInterface provided0 = new DefaultProvidedInterface("janse",
- String.class);
+ String.class);
required.get(0).setProvider(provided0);
- _scope.publishInterface(provided0, "hello");
+ Scope scope = getScope();
+ scope.publishInterface(provided0, "hello");
X6 obj = new X6();
assertNull(obj.getHost());
assertNull(obj.getPort());
- config.inject(_scope, obj);
+ config.inject(scope, obj);
assertEquals("hello", obj.getHost());
assertNull(obj.getPort());
}
- public void testRemoveNonExisting() {
- final SetterConfiguration config = new SetterConfiguration(X6.class);
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- config.remove("bladibla");
- }
- }, IllegalArgumentException.class);
- }
-
- public void testOverridingSetters() {
- SetterConfiguration config = new SetterConfiguration(X10.class).initAllSetters();
- assertEquals(2, config.getRequiredInterfaces().size());
- List<Method> methods = config.getSetters();
- assertEquals(2, methods.size());
- for (Method method: methods) {
- assertEquals(X10.class, method.getDeclaringClass());
- }
-
- }
+ public void testRemoveNonExisting() {
+ final SetterConfiguration config = new SetterConfiguration(X6.class);
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ config.remove("bladibla");
+ }
+ }, IllegalArgumentException.class);
+ }
+
+ public void testOverridingSetters() {
+ SetterConfiguration config = new SetterConfiguration(X10.class)
+ .initAllSetters();
+ assertEquals(2, config.getRequiredInterfaces().size());
+
+ List<Method> methods = config.getSetters();
+ assertEquals(2, methods.size());
+
+ for (Method method : methods) {
+ assertEquals(X10.class, method.getDeclaringClass());
+ }
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X1 {
- public X1() {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x1()");
- }
+ /**
+ * Creates a new X1 object.
+ */
+ public X1() {
+ AdapterTestCase.getEventTracker().eventOccurred("x1()");
+ }
- public X1(String aValue) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x1(" + aValue + ")");
- }
-}
\ No newline at end of file
+ /**
+ * Creates a new X1 object.
+ *
+ */
+ public X1(String aValue) {
+ AdapterTestCase.getEventTracker().eventOccurred("x1(" + aValue + ")");
+ }
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X10 extends X6 {
+ @Override
+ public void setHost(String aHost) {
+ super.setHost(aHost);
+ }
-
- @Override
- public void setHost(String aHost) {
- super.setHost(aHost);
- }
-
- @Override
- public String getHost() {
- return super.getHost();
- }
-
- @Override
- public Integer getPort() {
- return super.getPort();
- }
-
- @Override
- public void setPort(Integer aPort) {
- super.setPort(aPort);
- }
-
+ @Override
+ public String getHost() {
+ return super.getHost();
+ }
+
+ @Override
+ public Integer getPort() {
+ return super.getPort();
+ }
+
+ @Override
+ public void setPort(Integer aPort) {
+ super.setPort(aPort);
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X11 {
-
-
- public void setX(String aValue) {
-
- }
-
- public void setY(String aValue) {
-
- }
+ public void setX(String aValue) {
+ }
+ public void setY(String aValue) {
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X2 {
- public X2(Integer aInteger) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x2(" + aInteger + ")");
- }
+ /**
+ * Creates a new X2 object.
+ *
+ */
+ public X2(Integer aInteger) {
+ AdapterTestCase.getEventTracker().eventOccurred("x2(" + aInteger + ")");
+ }
- public X2(String aValue) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x2(" + aValue + ")");
- }
-}
\ No newline at end of file
+ /**
+ * Creates a new X2 object.
+ *
+ */
+ public X2(String aValue) {
+ AdapterTestCase.getEventTracker().eventOccurred("x2(" + aValue + ")");
+ }
+}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X3 {
- public X3() {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x3()");
- }
+ /**
+ * Creates a new X3 object.
+ */
+ public X3() {
+ AdapterTestCase.getEventTracker().eventOccurred("x3()");
+ }
- protected X3(String aValue) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x3(" + aValue + ")");
- }
-}
\ No newline at end of file
+ /**
+ * Creates a new X3 object.
+ *
+ */
+ protected X3(String aValue) {
+ AdapterTestCase.getEventTracker().eventOccurred("x3(" + aValue + ")");
+ }
+}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X4 {
+ private X1 x1;
+
+ /**
+ * Creates a new X4 object.
+ *
+ */
+ public X4(X1 aX1) {
+ AdapterTestCase.getEventTracker().eventOccurred("x4(x1)");
+ x1 = aX1;
+ }
- private X1 _x1;
-
- public X4(X1 aX1) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x4(x1)");
- _x1 = aX1;
- }
-
- public X1 getX1() {
- return _x1;
- }
+ public X1 getX1() {
+ return x1;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X5 {
-
- private String _value;
- private Integer _xyz;
-
- public X5() {
-
- }
-
- public void setValue(String aValue) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x5.setValue(" + aValue + ")");
- _value = aValue;
- }
-
- public String getValue() {
- return _value;
+ private String value;
+
+ private Integer xyz;
+
+ /**
+ * Creates a new X5 object.
+ */
+ public X5() {
+ }
+
+ public void setValue(String aValue) {
+ AdapterTestCase.getEventTracker().eventOccurred("x5.setValue(" + aValue +
+ ")");
+ value = aValue;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void doSomething() {
+ // Empty.
+ }
+
+ private void setXyz(int aXyz) {
+ xyz = aXyz;
+ }
+
+ public Integer getXyz() {
+ return xyz;
}
-
- public void doSomething() {
- // Empty.
- }
-
- private void setXyz(int aXyz) {
- _xyz = aXyz;
- }
-
- public Integer getXyz() {
- return _xyz;
- }
-}
\ No newline at end of file
+}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X6 {
-
- private String _host;
- private Integer _port;
-
- public X6() {
-
- }
+ private String host;
+
+ private Integer port;
- public Integer getPort() {
- return _port;
+ /**
+ * Creates a new X6 object.
+ */
+ public X6() {
}
-
- public void setPort(Integer aPort) {
- _port = aPort;
+
+ public Integer getPort() {
+ return port;
}
-
- public String getHost() {
- return _host;
+
+ public void setPort(Integer aPort) {
+ port = aPort;
}
-
- public void setHost(String aHost) {
- _host = aHost;
+
+ public String getHost() {
+ return host;
+ }
+
+ public void setHost(String aHost) {
+ host = aHost;
}
-}
\ No newline at end of file
+}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X7 {
-
- private String _host;
- private Integer _port;
- private Boolean _boolean;
-
- public X7(Boolean aBoolean) {
- _boolean = aBoolean;
- }
-
- public Boolean getBoolean() {
- return _boolean;
+ private String host;
+
+ private Integer port;
+
+ private Boolean flag;
+
+ /**
+ * Creates a new X7 object.
+ *
+ */
+ public X7(Boolean aBoolean) {
+ flag = aBoolean;
}
- public Integer getPort() {
- return _port;
+ public Boolean getBoolean() {
+ return flag;
}
-
- public void setPort(Integer aPort) {
- _port = aPort;
+
+ public Integer getPort() {
+ return port;
}
-
- public String getHost() {
- return _host;
+
+ public void setPort(Integer aPort) {
+ port = aPort;
+ }
+
+ public String getHost() {
+ return host;
}
-
- public void setHost(String aHost) {
- _host = aHost;
+
+ public void setHost(String aHost) {
+ host = aHost;
}
-}
\ No newline at end of file
+}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X8 {
+ private X1 x1;
+
+ private X4 x4;
+
+ /**
+ * Creates a new X8 object.
+ *
+ */
+ public X8(X1 aX1) {
+ AdapterTestCase.getEventTracker().eventOccurred("x8(x1)");
+ x1 = aX1;
+ }
- private X1 _x1;
- private X4 _x4;
-
- public X8(X1 aX1) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x8(x1)");
- _x1 = aX1;
- }
-
- public void setX4(X4 aX4) {
- AdapterTestCase.EVENT_TRACKER.eventOccurred("x8.setX4(x4)");
- _x4 = aX4;
+ public void setX4(X4 aX4) {
+ AdapterTestCase.getEventTracker().eventOccurred("x8.setX4(x4)");
+ x4 = aX4;
}
-
- public X4 getX4() {
- return _x4;
+
+ public X4 getX4() {
+ return x4;
+ }
+
+ public X1 getX1() {
+ return x1;
}
-
- public X1 getX1() {
- return _x1;
- }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.system.adapters;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class X9 extends X5 {
-
- private boolean _flag;
-
- public X9() {
-
- }
+ private boolean flag;
+
+ /**
+ * Creates a new X9 object.
+ */
+ public X9() {
+ }
+
+ public boolean isFlag() {
+ return flag;
+ }
- public boolean isFlag() {
- return _flag;
- }
-
public void setFlag(boolean aFlag) {
- _flag = aFlag;
- }
+ flag = aFlag;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.components;
-import java.util.Properties;
-
import org.wamblee.support.persistence.Database;
import org.wamblee.support.persistence.DerbyDatabase;
+
import org.wamblee.system.components.ORMappingConfig.DatabaseType;
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.Scope;
+import java.util.Properties;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DatabaseComponent extends AbstractComponent<Database> {
-
- private static ProvidedInterface DB_PROPS = new DefaultProvidedInterface("dbProps", Properties.class);
-
- private Database _database;
-
- public DatabaseComponent(String aName, Database aDatabase) {
- super(aName);
- _database = aDatabase;
+ private static ProvidedInterface DB_PROPS = new DefaultProvidedInterface(
+ "dbProps", Properties.class);
+
+ private Database database;
+
+ /**
+ * Creates a new DatabaseComponent object.
+ *
+ */
+ public DatabaseComponent(String aName, Database aDatabase) {
+ super(aName);
+ database = aDatabase;
addProvidedInterface(DB_PROPS);
}
@Override
protected Database doStart(Scope aScope) {
- _database.start();
-
+ database.start();
+
Properties props = new Properties();
- if ( _database instanceof DerbyDatabase ) {
+
+ if (database instanceof DerbyDatabase) {
props.put("database.type", DatabaseType.DERBY.toString());
- } else {
- throw new IllegalArgumentException("Unknown database type " + _database);
+ } else {
+ throw new IllegalArgumentException("Unknown database type " +
+ database);
}
- //props.put("database.driver", _database.getDriverClassName());
- props.put("database.url", _database.getJdbcUrl());
- props.put("database.username", _database.getUsername());
- props.put("database.password", _database.getPassword());
+
+ // props.put("database.driver", database.getDriverClassName());
+ props.put("database.url", database.getJdbcUrl());
+ props.put("database.username", database.getUsername());
+ props.put("database.password", database.getPassword());
addInterface(DB_PROPS, props, aScope);
- return _database;
+
+ return database;
}
@Override
protected void doStop(Database aRuntime) {
- _database.stop();
+ database.stop();
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.components;
import org.wamblee.support.persistence.DatabaseBuilder;
+
import org.wamblee.system.container.Container;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DatabaseComponentFactory {
-
public static void addDatabaseConfig(Container aContainer) {
try {
- aContainer.addComponent(new DatabaseComponent("db",
- DatabaseBuilder.getDatabase()));
+ aContainer.addComponent(new DatabaseComponent("db", DatabaseBuilder
+ .getDatabase()));
} catch (Exception e) {
throw new RuntimeException("Could not add database configuration",
- e);
+ e);
}
}
-
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.container;
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+
import org.wamblee.test.EventTracker;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class Application extends AbstractComponent<Object> {
- public static RequiredInterface[] required(boolean aOptional,
- String aPrefix) {
- return new RequiredInterface[] {
- new DefaultRequiredInterface(aPrefix + "string", String.class,
- aOptional),
- new DefaultRequiredInterface(aPrefix + "integer",
- Integer.class, aOptional) };
- }
+ private EventTracker<String> tracker;
- public static RequiredInterface[] required(boolean aOptional) {
- return required(aOptional, "");
- }
+ private String string;
+
+ private Integer integer;
- private EventTracker<String> _tracker;
- private String _string;
- private Integer _integer;
- private double _random;
+ private double random;
+ /**
+ * Creates a new Application object.
+ */
public Application() {
this("application");
}
+ /**
+ * Creates a new Application object.
+ *
+ */
public Application(String aName) {
this(aName, "");
}
+ /**
+ * Creates a new Application object.
+ *
+ */
public Application(String aName, String aPrefix) {
- super(aName, new ProvidedInterface[0], required(false,
- aPrefix));
- _random = Math.random();
+ super(aName, new ProvidedInterface[0], required(false, aPrefix));
+ random = Math.random();
}
+ /**
+ * Creates a new Application object.
+ *
+ */
public Application(boolean aIsOptinal) {
super("application", new ProvidedInterface[0], required(true, ""));
}
+ /**
+ * Creates a new Application object.
+ *
+ */
public Application(EventTracker<String> aTracker) {
this();
- _tracker = aTracker;
+ tracker = aTracker;
+ }
+
+ public static RequiredInterface[] required(boolean aOptional, String aPrefix) {
+ return new RequiredInterface[] {
+ new DefaultRequiredInterface(aPrefix + "string", String.class,
+ aOptional),
+ new DefaultRequiredInterface(aPrefix + "integer", Integer.class,
+ aOptional) };
+ }
+
+ public static RequiredInterface[] required(boolean aOptional) {
+ return required(aOptional, "");
}
@Override
public Object doStart(Scope aScope) {
track("start." + getName());
- _string = aScope.getInterfaceImplementation(getRequiredInterfaces()
- .get(0).getProvider(), String.class);
- _integer = aScope.getInterfaceImplementation(getRequiredInterfaces()
- .get(1).getProvider(), Integer.class);
- return _random;
+ string = aScope.getInterfaceImplementation(getRequiredInterfaces().get(
+ 0).getProvider(), String.class);
+ integer = aScope.getInterfaceImplementation(getRequiredInterfaces()
+ .get(1).getProvider(), Integer.class);
+
+ return random;
}
public String getString() {
- return _string;
+ return string;
}
public Integer getInteger() {
- return _integer;
+ return integer;
}
@Override
public void doStop(Object aRuntime) {
track("stop." + getName());
- if (_random != (Double) aRuntime) {
- throw new IllegalArgumentException("Wrong runtime: expected "
- + _random + " but got " + aRuntime);
+
+ if (random != (Double) aRuntime) {
+ throw new IllegalArgumentException("Wrong runtime: expected " +
+ random + " but got " + aRuntime);
}
}
private void track(String aString) {
- if (_tracker == null) {
+ if (tracker == null) {
return;
}
- _tracker.eventOccurred(aString);
+
+ tracker.eventOccurred(aString);
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.container;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
import junit.framework.TestCase;
+import org.junit.internal.requests.IgnoredClassRunner;
import org.wamblee.general.Pair;
+
import org.wamblee.system.core.Component;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.DefaultRequiredInterface;
import org.wamblee.system.core.Scope;
import org.wamblee.system.core.StringComponent;
import org.wamblee.system.core.SystemAssemblyException;
+
import org.wamblee.test.AssertionUtils;
import org.wamblee.test.EventTracker;
-public class ContainerTest extends TestCase {
+import java.io.Serializable;
+
+import java.util.ArrayList;
+import java.util.List;
- private EventTracker<String> _tracker;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- _tracker = new EventTracker<String>();
- }
-
- private static class MyMultiple implements Serializable, Runnable {
- @Override
- public void run() {
- // Empty
- }
- }
-
- private List<Pair<ProvidedInterface, Component>> createProvidedInput(
- ProvidedInterface[] aProvided, Component aProvider) {
- List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
- for (ProvidedInterface provided : aProvided) {
- result.add(new Pair<ProvidedInterface, Component>(provided,
- aProvider));
- }
- return result;
- }
-
- public void testEnvironmentApplication() {
- Environment environment = new Environment(_tracker);
- Application application = new Application(_tracker);
- Container container = new Container("root", new Component[] {
- environment, application }, new ProvidedInterface[0],
- new RequiredInterface[0]);
- Scope scope = container.start();
- assertTrue(container.isSealed());
- AssertionUtils.assertEquals(new String[] { "start.environment",
- "start.application" }, _tracker.getEvents(
- Thread.currentThread()).toArray(new String[0]));
- assertEquals(0, scope.getProvidedInterfaces().size());
-
- assertEquals(environment.getString(), application.getString());
- assertEquals(environment.getInteger(), application.getInteger());
-
- }
-
- public void testEnvironmentApplicationSimpleConstructor() {
- Environment environment = new Environment(_tracker);
- Application application = new Application(_tracker);
- Container container = new Container("root").addComponent(environment)
- .addComponent(application);
-
- Scope scope = container.start();
- AssertionUtils.assertEquals(new String[] { "start.environment",
- "start.application" }, _tracker.getEvents(
- Thread.currentThread()).toArray(new String[0]));
- assertEquals(0, scope.getProvidedInterfaces().size());
-
- assertEquals(environment.getString(), application.getString());
- assertEquals(environment.getInteger(), application.getInteger());
-
- }
-
- public void testApplicationEnvironment() {
- try {
- Component<?> environment = new Environment();
- Component<?> application = new Application();
- Container container = new Container("root", new Component[] {
- application, environment }, new ProvidedInterface[0],
- new RequiredInterface[0]);
- container.start();
- } catch (SystemAssemblyException e) {
- // e.printStackTrace();
- return;
- }
- fail();
- }
-
- public void testComposite() {
- Component<?> environment = new Environment(_tracker);
- Component<?> application = new Application(_tracker);
- assertEquals(0, _tracker.getEventCount());
-
- Container system = new Container("all", new Component[] { environment,
- application }, new ProvidedInterface[0],
- new RequiredInterface[0]);
- Scope runtime = system.start();
- List<RequiredInterface> required = system.getRequiredInterfaces();
- assertEquals(0, required.size());
- List<ProvidedInterface> provided = system.getProvidedInterfaces();
- assertEquals(0, provided.size());
-
- AssertionUtils.assertEquals(new String[] { "start.environment",
- "start.application" }, _tracker.getEvents(
- Thread.currentThread()).toArray(new String[0]));
- _tracker.clear();
-
- system.stop(runtime);
- AssertionUtils.assertEquals(new String[] { "stop.application",
- "stop.environment" }, _tracker
- .getEvents(Thread.currentThread()).toArray(new String[0]));
-
- }
-
- public void testCompositeWithWrongProvidedInfo() {
- try {
- Component<?> environment = new Environment();
- Component<?> application = new Application();
- Container system = new Container("all", new Component[] {
- environment, application },
- new ProvidedInterface[] { new DefaultProvidedInterface(
- "float", Float.class) },
- new DefaultRequiredInterface[0]);
- system.validate();
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testCompositeRequiredInterfaceNotProvided() {
- try {
- Component<?> environment = new Environment();
- Component<?> application = new Application();
- Container system = new Container("all", new Component[] {
- environment, application }, new ProvidedInterface[0],
- new RequiredInterface[] { new DefaultRequiredInterface(
- "string", String.class) });
- system.start();
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testCompositeWithSuperfluousRequiredInfo() {
- Component<?> environment = new Environment();
- Component<?> application = new Application();
- Container system = new Container("all", new Component[] { environment,
- application }, new ProvidedInterface[0],
- new RequiredInterface[] { new DefaultRequiredInterface("float",
- Float.class) });
- system.getRequiredInterfaces().get(0).setProvider(
- new DefaultProvidedInterface("hallo", Float.class));
- system.start();
- List<RequiredInterface> required = system.getRequiredInterfaces();
- assertEquals(1, required.size());
- List<ProvidedInterface> provided = system.getProvidedInterfaces();
- assertEquals(0, provided.size());
- }
-
- public void testCompositeWithExternalDependencesNotProvided() {
- try {
- Component<?> application = new Application();
-
- Container system = new Container("all",
- new Component[] { application }, new ProvidedInterface[0],
- application.getRequiredInterfaces().toArray(
- new RequiredInterface[0]));
- system.start();
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testDuplicateComponent() {
- try {
- Component<?> comp1 = new Application();
- Component<?> comp2 = new Application();
- Container system = new Container("top");
- system.addComponent(comp1).addComponent(comp2);
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testInconsistentHierarchy() {
- try {
- Component<?> comp = new Application();
- Container system = new Container("top").addComponent(comp);
- Container system2 = new Container("top2").addComponent(comp);
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testCompositeWithExternalDependencesProvided() {
-
- Component<?> environment = new Environment();
- Component<?> application = new Application();
- Container system = new Container("all",
- new Component[] { application }, new ProvidedInterface[0],
- application.getRequiredInterfaces().toArray(
- new RequiredInterface[0]));
- environment.start(new DefaultScope(new ProvidedInterface[0]));
- system.getRequiredInterfaces().get(0).setProvider(
- environment.getProvidedInterfaces().get(0));
- system.getRequiredInterfaces().get(1).setProvider(
- environment.getProvidedInterfaces().get(1));
-
- system.start();
- List<RequiredInterface> required = system.getRequiredInterfaces();
- assertEquals(2, required.size());
- List<ProvidedInterface> provided = system.getProvidedInterfaces();
- assertEquals(0, provided.size());
-
- }
-
- public void testAmbiguousInterfaces() {
- try {
- Component<?> environment1 = new Environment();
- Component<?> environment2 = new Environment();
- Component<?> application = new Application();
- Container container = new Container("root", new Component[] {
- environment1, environment2, application },
- new ProvidedInterface[0], new RequiredInterface[0]);
- container.start();
-
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testIncompleteRequirements() {
- try {
- Component<?> application = new Application();
- Container system = new Container("all",
- new Component[] { application }, new ProvidedInterface[0],
- new RequiredInterface[0]);
- system.start();
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testEnvironmentApplicationRollbackOnException()
- throws Exception {
- Environment environment = new Environment(_tracker);
- Application application = new Application() {
- @Override
- public Object doStart(Scope aScope) {
- throw new RuntimeException();
- }
- };
-
- try {
- Container container = new Container("root", new Component[] {
- environment, application }, new ProvidedInterface[0],
- new RequiredInterface[0]);
-
- container.start();
- } catch (RuntimeException e) {
- AssertionUtils.assertEquals(new String[] { "start.environment",
- "stop.environment" }, _tracker.getEvents(
- Thread.currentThread()).toArray(new String[0]));
- return;
- }
- fail();
- }
-
- public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
- throws Exception {
-
- Environment environment = new Environment(_tracker);
- // Application 1 will throw an exception while stopping.
- Application application1 = new Application("app1") {
- @Override
- public void doStop(Object aRuntime) {
- throw new RuntimeException();
- }
- };
-
- // application 2 will throw an exception while starting
- Application application2 = new Application("app2") {
- public Object doStart(Scope aScope) {
- throw new RuntimeException();
- }
- };
-
- try {
- Container container = new Container("root", new Component[] {
- environment, application1, application2 },
- new ProvidedInterface[0], new RequiredInterface[0]);
-
- container.start();
- } catch (RuntimeException e) {
- AssertionUtils.assertEquals(new String[] { "start.environment",
- "stop.environment" }, _tracker.getEvents(
- Thread.currentThread()).toArray(new String[0]));
- return;
- }
- fail();
- }
-
- public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
- Application application = new Application(true);
- Container container = new Container("top",
- new Component[] { application }, new ProvidedInterface[0],
- Application.required(true));
- Environment env = new Environment();
- container.getRequiredInterfaces().get(0).setProvider(
- env.getProvidedInterfaces().get(0));
- container.getRequiredInterfaces().get(1).setProvider(
- env.getProvidedInterfaces().get(1));
- Scope external = new DefaultScope(env.getProvidedInterfaces());
- env.start(external);
-
- container.start(external);
- assertSame(env.getProvidedInterfaces().get(0), container
- .getRequiredInterfaces().get(0).getProvider());
- assertSame(env.getProvidedInterfaces().get(1), container
- .getRequiredInterfaces().get(1).getProvider());
- assertSame(env.getProvidedInterfaces().get(0), application
- .getRequiredInterfaces().get(0).getProvider());
- assertSame(env.getProvidedInterfaces().get(1), application
- .getRequiredInterfaces().get(1).getProvider());
- }
-
- public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
- Application application = new Application(true);
- Container container = new Container("top",
- new Component[] { application }, new ProvidedInterface[0],
- Application.required(true));
- Environment env = new Environment();
- container.getRequiredInterfaces().get(0).setProvider(
- env.getProvidedInterfaces().get(0));
- Scope external = new DefaultScope(new ProvidedInterface[0]);
- external.publishInterface(env.getProvidedInterfaces().get(0), env
- .getString());
- container.start(external);
- assertSame(env.getProvidedInterfaces().get(0), container
- .getRequiredInterfaces().get(0).getProvider());
- assertNull(container.getRequiredInterfaces().get(1).getProvider());
- assertSame(env.getProvidedInterfaces().get(0), application
- .getRequiredInterfaces().get(0).getProvider());
- assertNull(application.getRequiredInterfaces().get(1).getProvider());
- }
-
- public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
- Application application = new Application();
- Container container = new Container("top",
- new Component[] { application }, new ProvidedInterface[0],
- Application.required(true));
- Environment env = new Environment();
- container.getRequiredInterfaces().get(0).setProvider(
- env.getProvidedInterfaces().get(0));
- container.getRequiredInterfaces().get(1).setProvider(
- env.getProvidedInterfaces().get(1));
- try {
- container.start();
- } catch (SystemAssemblyException e) {
- return;
- }
- fail();
- }
-
- public void testSealed() {
- final Container container = new Container("xx");
- assertFalse(container.isSealed());
- container.start();
- assertTrue(container.isSealed());
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.addComponent(new Application());
- }
- }, SystemAssemblyException.class);
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectRequiredProvided("x", "y", "a", "b");
- }
- }, SystemAssemblyException.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalRequired("x", "y", "a");
- }
- }, SystemAssemblyException.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalProvided("x", "y", "z");
- }
- }, SystemAssemblyException.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.addProvidedInterface(new DefaultProvidedInterface(
- "xx", String.class));
- }
- }, SystemAssemblyException.class);
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.addRequiredInterface(new DefaultRequiredInterface(
- "xx", String.class));
- }
- }, SystemAssemblyException.class);
- }
-
- public void testRestriction() {
- Environment env1 = new Environment("env1");
- Environment env2 = new Environment("env2");
- Application app = new Application("app");
- Container container = new Container("top").addComponent(env1)
- .addComponent(env2).addComponent(app);
- container.connectRequiredProvided("app", null, "env1", null);
- container.start();
- assertEquals(env1.getString(), app.getString());
- assertEquals(env1.getInteger(), app.getInteger());
- assertFalse(env2.getString().equals(app.getString()));
- assertFalse(env2.getInteger().equals(app.getInteger()));
- }
-
- public void testRestrictionWithFromAndToInterfaceName() {
- Environment env1 = new Environment("env1");
- Environment env2 = new Environment("env2");
- Application app = new Application("app");
- Container container = new Container("top").addComponent(env1)
- .addComponent(env2).addComponent(app);
- container.connectRequiredProvided("app", app.getRequiredInterfaces()
- .get(0).getName(), "env1", env1.getProvidedInterfaces().get(0)
- .getName());
- container.connectRequiredProvided("app", app.getRequiredInterfaces()
- .get(1).getName(), "env2", env2.getProvidedInterfaces().get(1)
- .getName());
- container.start();
- assertEquals(env1.getString(), app.getString());
- assertEquals(env2.getInteger(), app.getInteger());
- assertFalse(env2.getString().equals(app.getString()));
- assertFalse(env1.getInteger().equals(app.getInteger()));
- }
-
- public void testRestrictionWrongComponentNames() {
- Environment env1 = new Environment("env1");
- Environment env2 = new Environment("env2");
- Application app = new Application("app");
- final Container container = new Container("top").addComponent(env1)
- .addComponent(env2).addComponent(app);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectRequiredProvided("app2", null, "env1", null);
- }
- }, SystemAssemblyException.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectRequiredProvided("app", null, "env3", null);
- }
- }, SystemAssemblyException.class);
- }
-
- public void testRestrictionWrongInterfaceNames() {
- final Environment env1 = new Environment("env1");
- Environment env2 = new Environment("env2");
- final Application app = new Application("app");
- final Container container = new Container("top").addComponent(env1)
- .addComponent(env2).addComponent(app);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectRequiredProvided("app", app
- .getRequiredInterfaces().get(0).getName()
- + "xxx", "env1", null);
- }
- }, SystemAssemblyException.class);
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectRequiredProvided("app", null, "env1", env1
- .getProvidedInterfaces().get(0).getName()
- + "yyy");
- }
- }, SystemAssemblyException.class);
- }
-
- public void testProvidedInDifferentScopes() {
- // Scoping problem occurred. Externally and internally provided
- // components clashed
- // because unique id generation in the scope was wrong.
-
- StringComponent str = new StringComponent("string");
- Application app = new Application("app");
- Container container = new Container("top").addComponent(str)
- .addComponent(app);
- container.addRequiredInterface(new DefaultRequiredInterface("integer",
- Integer.class));
-
- ProvidedInterface provided = new DefaultProvidedInterface("hallo",
- Integer.class);
- container.getRequiredInterfaces().get(0).setProvider(provided);
-
- Scope external = new DefaultScope(new ProvidedInterface[0]);
- external.publishInterface(provided, 100);
- Scope scope = container.start(external);
- }
-
- public void testProvidedInterfaces() {
- Environment env = new Environment(_tracker);
- Container envcontainer = new Container("0").addComponent(env)
- .addProvidedInterface(
- new DefaultProvidedInterface("string", String.class))
- .addProvidedInterface(
- new DefaultProvidedInterface("integer", Integer.class));
- Scope scope = envcontainer.start();
-
- AssertionUtils.assertEquals(new String[] { "start.environment" },
- _tracker.getEvents(Thread.currentThread()).toArray(
- new String[0]));
-
- envcontainer.stop(scope);
- }
-
- public void testCoupleTwoContainers() {
- Environment env = new Environment(_tracker);
- Container envcontainer = new Container("0").addComponent(env)
- .addProvidedInterface(
- new DefaultProvidedInterface("string", String.class))
- .addProvidedInterface(
- new DefaultProvidedInterface("integer", Integer.class));
-
- Application app = new Application(_tracker);
- Container appcontainer = new Container("1").addComponent(app)
- .addRequiredInterface(
- new DefaultRequiredInterface("string", String.class))
- .addRequiredInterface(
- new DefaultRequiredInterface("integer", Integer.class));
-
- Container top = new Container("top");
- top.addComponent(envcontainer).addComponent(appcontainer);
-
- top.start();
- AssertionUtils.assertEquals(new String[] { "start.environment",
- "start.application" }, _tracker.getEvents(
- Thread.currentThread()).toArray(new String[0]));
-
- }
-
- public void testNonUniqueRequiredInterface() {
- final Container container = new Container("top");
- container.addRequiredInterface(new DefaultRequiredInterface("i",
- Integer.class));
- container.addRequiredInterface(new DefaultRequiredInterface("x",
- String.class));
- container.addRequiredInterface(new DefaultRequiredInterface("y",
- String.class));
-
- Application app = new Application("1");
- container.addComponent(app);
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.start();
- }
- }, SystemAssemblyException.class);
-
- container.connectExternalRequired("1", app.getRequiredInterfaces().get(
- 0).getName(), "y");
-
- ProvidedInterface i = new DefaultProvidedInterface("i", Integer.class);
- ProvidedInterface x = new DefaultProvidedInterface("x", String.class);
- ProvidedInterface y = new DefaultProvidedInterface("y", String.class);
-
- Scope externalScope = new DefaultScope(new ProvidedInterface[0]);
-
- externalScope.publishInterface(i, 100);
- externalScope.publishInterface(x, "x-value");
- externalScope.publishInterface(y, "y-value");
-
- container.getRequiredInterfaces().get(0).setProvider(i);
- container.getRequiredInterfaces().get(1).setProvider(x);
- container.getRequiredInterfaces().get(2).setProvider(y);
-
- Scope runtime = container.start(externalScope);
-
- assertEquals("y-value", app.getString());
-
- }
-
- public void testNonUniqueRequiredInterfaceWrongNames() {
- final Container container = new Container("top");
- container.addRequiredInterface(new DefaultRequiredInterface("i",
- Integer.class));
- container.addRequiredInterface(new DefaultRequiredInterface("x",
- String.class));
- container.addRequiredInterface(new DefaultRequiredInterface("y",
- String.class));
-
- final Application app = new Application("1");
- container.addComponent(app);
-
- // wrong component name.
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalRequired("2", "x", "y");
- }
- }, SystemAssemblyException.class);
-
- // Wrong interface name of component.
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalRequired("1", app
- .getRequiredInterfaces().get(0).getName()
- + "xxx", "y");
- }
- }, SystemAssemblyException.class);
-
- // Wrong external interface name of container
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalRequired("1", app
- .getRequiredInterfaces().get(0).getName(), "z");
- }
- }, SystemAssemblyException.class);
- }
-
- public void testNonUniqueProvidedInterface() {
-
- final Container container = new Container("top")
- .addProvidedInterface(new DefaultProvidedInterface("external",
- String.class));
- Environment env1 = new Environment("env1");
- Environment env2 = new Environment("env2");
-
- container.addComponent(env1);
- container.addComponent(env2);
-
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.start();
- }
- }, SystemAssemblyException.class);
-
- // now choose env2
-
- container.connectExternalProvided(container.getProvidedInterfaces()
- .get(0).getName(), env2.getName(), env2.getProvidedInterfaces()
- .get(0).getName());
-
- Scope scope = container.start();
-
- // check the value of the provided interface of the container
-
- String value = scope.getInterfaceImplementation(container
- .getProvidedInterfaces().get(0), String.class);
- assertNotNull(value);
- assertEquals(value, env2.getString());
- assertFalse(value.equals(env1.getString()));
- }
-
- public void testNonUniqueProvidedInterfaceWrongNames() {
-
- final Container container = new Container("top")
- .addProvidedInterface(new DefaultProvidedInterface("external",
- String.class));
- final Environment env1 = new Environment("env1");
- final Environment env2 = new Environment("env2");
-
- container.addComponent(env1);
- container.addComponent(env2);
-
- // Wrong external provided interface name
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalProvided(container
- .getProvidedInterfaces().get(0).getName()
- + "xx", "env1", env1.getProvidedInterfaces().get(0)
- .getName());
- }
- }, SystemAssemblyException.class);
-
- // Wrong provided interface name.
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalProvided(container
- .getProvidedInterfaces().get(0).getName(), "env1", env1
- .getProvidedInterfaces().get(0).getName()
- + "xx");
- }
- }, SystemAssemblyException.class);
-
- // Wrong provided component
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
- @Override
- public void run() throws Exception {
- container.connectExternalProvided(container
- .getProvidedInterfaces().get(0).getName(), "env3", env1
- .getProvidedInterfaces().get(0).getName());
- }
- }, SystemAssemblyException.class);
- }
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ContainerTest extends TestCase {
+ private EventTracker<String> tracker;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ tracker = new EventTracker<String>();
+ }
+
+ private List<Pair<ProvidedInterface, Component>> createProvidedInput(
+ ProvidedInterface[] aProvided, Component aProvider) {
+ List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
+
+ for (ProvidedInterface provided : aProvided) {
+ result.add(new Pair<ProvidedInterface, Component>(provided,
+ aProvider));
+ }
+
+ return result;
+ }
+
+ public void testEnvironmentApplication() {
+ Environment environment = new Environment(tracker);
+ Application application = new Application(tracker);
+ Container container = new Container("root", new Component[] {
+ environment, application }, new ProvidedInterface[0],
+ new RequiredInterface[0]);
+ Scope scope = container.start();
+ assertTrue(container.isSealed());
+ AssertionUtils.assertEquals(new String[] { "start.environment",
+ "start.application" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+ assertEquals(0, scope.getProvidedInterfaces().size());
+
+ assertEquals(environment.getString(), application.getString());
+ assertEquals(environment.getInteger(), application.getInteger());
+ }
+
+ public void testEnvironmentApplicationSimpleConstructor() {
+ Environment environment = new Environment(tracker);
+ Application application = new Application(tracker);
+ Container container = new Container("root").addComponent(environment)
+ .addComponent(application);
+
+ Scope scope = container.start();
+ AssertionUtils.assertEquals(new String[] { "start.environment",
+ "start.application" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+ assertEquals(0, scope.getProvidedInterfaces().size());
+
+ assertEquals(environment.getString(), application.getString());
+ assertEquals(environment.getInteger(), application.getInteger());
+ }
+
+ public void testApplicationEnvironment() {
+ try {
+ Component<?> environment = new Environment();
+ Component<?> application = new Application();
+ Container container = new Container("root", new Component[] {
+ application, environment }, new ProvidedInterface[0],
+ new RequiredInterface[0]);
+ container.start();
+ } catch (SystemAssemblyException e) {
+ // e.printStackTrace();
+ return;
+ }
+
+ fail();
+ }
+
+ public void testComposite() {
+ Component<?> environment = new Environment(tracker);
+ Component<?> application = new Application(tracker);
+ assertEquals(0, tracker.getEventCount());
+
+ Container system = new Container("all", new Component[] { environment,
+ application }, new ProvidedInterface[0], new RequiredInterface[0]);
+ Scope runtime = system.start();
+ List<RequiredInterface> required = system.getRequiredInterfaces();
+ assertEquals(0, required.size());
+
+ List<ProvidedInterface> provided = system.getProvidedInterfaces();
+ assertEquals(0, provided.size());
+
+ AssertionUtils.assertEquals(new String[] { "start.environment",
+ "start.application" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+ tracker.clear();
+
+ system.stop(runtime);
+ AssertionUtils.assertEquals(new String[] { "stop.application",
+ "stop.environment" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+ }
+
+ public void testCompositeWithWrongProvidedInfo() {
+ try {
+ Component<?> environment = new Environment();
+ Component<?> application = new Application();
+ Container system = new Container("all", new Component[] {
+ environment, application },
+ new ProvidedInterface[] { new DefaultProvidedInterface("float",
+ Float.class) }, new DefaultRequiredInterface[0]);
+ system.validate();
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testCompositeRequiredInterfaceNotProvided() {
+ try {
+ Component<?> environment = new Environment();
+ Component<?> application = new Application();
+ Container system = new Container("all", new Component[] {
+ environment, application }, new ProvidedInterface[0],
+ new RequiredInterface[] { new DefaultRequiredInterface(
+ "string", String.class) });
+ system.start();
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testCompositeWithSuperfluousRequiredInfo() {
+ Component<?> environment = new Environment();
+ Component<?> application = new Application();
+ Container system = new Container("all", new Component[] { environment,
+ application }, new ProvidedInterface[0],
+ new RequiredInterface[] { new DefaultRequiredInterface("float",
+ Float.class) });
+ system.getRequiredInterfaces().get(0).setProvider(
+ new DefaultProvidedInterface("hallo", Float.class));
+ system.start();
+
+ List<RequiredInterface> required = system.getRequiredInterfaces();
+ assertEquals(1, required.size());
+
+ List<ProvidedInterface> provided = system.getProvidedInterfaces();
+ assertEquals(0, provided.size());
+ }
+
+ public void testCompositeWithExternalDependencesNotProvided() {
+ try {
+ Component<?> application = new Application();
+
+ Container system = new Container("all",
+ new Component[] { application }, new ProvidedInterface[0],
+ application.getRequiredInterfaces().toArray(
+ new RequiredInterface[0]));
+ system.start();
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testDuplicateComponent() {
+ try {
+ Component<?> comp1 = new Application();
+ Component<?> comp2 = new Application();
+ Container system = new Container("top");
+ system.addComponent(comp1).addComponent(comp2);
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testInconsistentHierarchy() {
+ try {
+ Component<?> comp = new Application();
+ Container system = new Container("top").addComponent(comp);
+ Container system2 = new Container("top2").addComponent(comp);
+
+ ignoredVariable(system);
+ ignoredVariable(system2);
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ private static void ignoredVariable(Object aObject) {
+ // for findbugs.
+ }
+
+ public void testCompositeWithExternalDependencesProvided() {
+ Component<?> environment = new Environment();
+ Component<?> application = new Application();
+ Container system = new Container("all",
+ new Component[] { application }, new ProvidedInterface[0],
+ application.getRequiredInterfaces().toArray(
+ new RequiredInterface[0]));
+ environment.start(new DefaultScope(new ProvidedInterface[0]));
+ system.getRequiredInterfaces().get(0).setProvider(
+ environment.getProvidedInterfaces().get(0));
+ system.getRequiredInterfaces().get(1).setProvider(
+ environment.getProvidedInterfaces().get(1));
+
+ system.start();
+
+ List<RequiredInterface> required = system.getRequiredInterfaces();
+ assertEquals(2, required.size());
+
+ List<ProvidedInterface> provided = system.getProvidedInterfaces();
+ assertEquals(0, provided.size());
+ }
+
+ public void testAmbiguousInterfaces() {
+ try {
+ Component<?> environment1 = new Environment();
+ Component<?> environment2 = new Environment();
+ Component<?> application = new Application();
+ Container container = new Container("root", new Component[] {
+ environment1, environment2, application },
+ new ProvidedInterface[0], new RequiredInterface[0]);
+ container.start();
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testIncompleteRequirements() {
+ try {
+ Component<?> application = new Application();
+ Container system = new Container("all",
+ new Component[] { application }, new ProvidedInterface[0],
+ new RequiredInterface[0]);
+ system.start();
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testEnvironmentApplicationRollbackOnException()
+ throws Exception {
+ Environment environment = new Environment(tracker);
+ Application application = new Application() {
+ @Override
+ public Object doStart(Scope aScope) {
+ throw new RuntimeException();
+ }
+ };
+
+ try {
+ Container container = new Container("root", new Component[] {
+ environment, application }, new ProvidedInterface[0],
+ new RequiredInterface[0]);
+
+ container.start();
+ } catch (RuntimeException e) {
+ AssertionUtils.assertEquals(new String[] { "start.environment",
+ "stop.environment" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+
+ return;
+ }
+
+ fail();
+ }
+
+ public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
+ throws Exception {
+ Environment environment = new Environment(tracker);
+
+ // Application 1 will throw an exception while stopping.
+ Application application1 = new Application("app1") {
+ @Override
+ public void doStop(Object aRuntime) {
+ throw new RuntimeException();
+ }
+ };
+
+ // application 2 will throw an exception while starting
+ Application application2 = new Application("app2") {
+ public Object doStart(Scope aScope) {
+ throw new RuntimeException();
+ }
+ };
+
+ try {
+ Container container = new Container("root", new Component[] {
+ environment, application1, application2 },
+ new ProvidedInterface[0], new RequiredInterface[0]);
+
+ container.start();
+ } catch (RuntimeException e) {
+ AssertionUtils.assertEquals(new String[] { "start.environment",
+ "stop.environment" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+
+ return;
+ }
+
+ fail();
+ }
+
+ public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
+ Application application = new Application(true);
+ Container container = new Container("top",
+ new Component[] { application }, new ProvidedInterface[0],
+ Application.required(true));
+ Environment env = new Environment();
+ container.getRequiredInterfaces().get(0).setProvider(
+ env.getProvidedInterfaces().get(0));
+ container.getRequiredInterfaces().get(1).setProvider(
+ env.getProvidedInterfaces().get(1));
+
+ Scope external = new DefaultScope(env.getProvidedInterfaces());
+ env.start(external);
+
+ container.start(external);
+ assertSame(env.getProvidedInterfaces().get(0), container
+ .getRequiredInterfaces().get(0).getProvider());
+ assertSame(env.getProvidedInterfaces().get(1), container
+ .getRequiredInterfaces().get(1).getProvider());
+ assertSame(env.getProvidedInterfaces().get(0), application
+ .getRequiredInterfaces().get(0).getProvider());
+ assertSame(env.getProvidedInterfaces().get(1), application
+ .getRequiredInterfaces().get(1).getProvider());
+ }
+
+ public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
+ Application application = new Application(true);
+ Container container = new Container("top",
+ new Component[] { application }, new ProvidedInterface[0],
+ Application.required(true));
+ Environment env = new Environment();
+ container.getRequiredInterfaces().get(0).setProvider(
+ env.getProvidedInterfaces().get(0));
+
+ Scope external = new DefaultScope(new ProvidedInterface[0]);
+ external.publishInterface(env.getProvidedInterfaces().get(0), env
+ .getString());
+ container.start(external);
+ assertSame(env.getProvidedInterfaces().get(0), container
+ .getRequiredInterfaces().get(0).getProvider());
+ assertNull(container.getRequiredInterfaces().get(1).getProvider());
+ assertSame(env.getProvidedInterfaces().get(0), application
+ .getRequiredInterfaces().get(0).getProvider());
+ assertNull(application.getRequiredInterfaces().get(1).getProvider());
+ }
+
+ public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
+ Application application = new Application();
+ Container container = new Container("top",
+ new Component[] { application }, new ProvidedInterface[0],
+ Application.required(true));
+ Environment env = new Environment();
+ container.getRequiredInterfaces().get(0).setProvider(
+ env.getProvidedInterfaces().get(0));
+ container.getRequiredInterfaces().get(1).setProvider(
+ env.getProvidedInterfaces().get(1));
+
+ try {
+ container.start();
+ } catch (SystemAssemblyException e) {
+ return;
+ }
+
+ fail();
+ }
+
+ public void testSealed() {
+ final Container container = new Container("xx");
+ assertFalse(container.isSealed());
+ container.start();
+ assertTrue(container.isSealed());
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.addComponent(new Application());
+ }
+ }, SystemAssemblyException.class);
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectRequiredProvided("x", "y", "a", "b");
+ }
+ }, SystemAssemblyException.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalRequired("x", "y", "a");
+ }
+ }, SystemAssemblyException.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalProvided("x", "y", "z");
+ }
+ }, SystemAssemblyException.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.addProvidedInterface(new DefaultProvidedInterface(
+ "xx", String.class));
+ }
+ }, SystemAssemblyException.class);
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.addRequiredInterface(new DefaultRequiredInterface(
+ "xx", String.class));
+ }
+ }, SystemAssemblyException.class);
+ }
+
+ public void testRestriction() {
+ Environment env1 = new Environment("env1");
+ Environment env2 = new Environment("env2");
+ Application app = new Application("app");
+ Container container = new Container("top").addComponent(env1)
+ .addComponent(env2).addComponent(app);
+ container.connectRequiredProvided("app", null, "env1", null);
+ container.start();
+ assertEquals(env1.getString(), app.getString());
+ assertEquals(env1.getInteger(), app.getInteger());
+ assertFalse(env2.getString().equals(app.getString()));
+ assertFalse(env2.getInteger().equals(app.getInteger()));
+ }
+
+ public void testRestrictionWithFromAndToInterfaceName() {
+ Environment env1 = new Environment("env1");
+ Environment env2 = new Environment("env2");
+ Application app = new Application("app");
+ Container container = new Container("top").addComponent(env1)
+ .addComponent(env2).addComponent(app);
+ container.connectRequiredProvided("app", app.getRequiredInterfaces()
+ .get(0).getName(), "env1", env1.getProvidedInterfaces().get(0)
+ .getName());
+ container.connectRequiredProvided("app", app.getRequiredInterfaces()
+ .get(1).getName(), "env2", env2.getProvidedInterfaces().get(1)
+ .getName());
+ container.start();
+ assertEquals(env1.getString(), app.getString());
+ assertEquals(env2.getInteger(), app.getInteger());
+ assertFalse(env2.getString().equals(app.getString()));
+ assertFalse(env1.getInteger().equals(app.getInteger()));
+ }
+
+ public void testRestrictionWrongComponentNames() {
+ Environment env1 = new Environment("env1");
+ Environment env2 = new Environment("env2");
+ Application app = new Application("app");
+ final Container container = new Container("top").addComponent(env1)
+ .addComponent(env2).addComponent(app);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectRequiredProvided("app2", null, "env1", null);
+ }
+ }, SystemAssemblyException.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectRequiredProvided("app", null, "env3", null);
+ }
+ }, SystemAssemblyException.class);
+ }
+
+ public void testRestrictionWrongInterfaceNames() {
+ final Environment env1 = new Environment("env1");
+ Environment env2 = new Environment("env2");
+ final Application app = new Application("app");
+ final Container container = new Container("top").addComponent(env1)
+ .addComponent(env2).addComponent(app);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectRequiredProvided("app", app
+ .getRequiredInterfaces().get(0).getName() +
+ "xxx", "env1", null);
+ }
+ }, SystemAssemblyException.class);
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectRequiredProvided("app", null, "env1", env1
+ .getProvidedInterfaces().get(0).getName() +
+ "yyy");
+ }
+ }, SystemAssemblyException.class);
+ }
+
+ public void testProvidedInDifferentScopes() {
+ // Scoping problem occurred. Externally and internally provided
+ // components clashed
+ // because unique id generation in the scope was wrong.
+ StringComponent str = new StringComponent("string");
+ Application app = new Application("app");
+ Container container = new Container("top").addComponent(str)
+ .addComponent(app);
+ container.addRequiredInterface(new DefaultRequiredInterface("integer",
+ Integer.class));
+
+ ProvidedInterface provided = new DefaultProvidedInterface("hallo",
+ Integer.class);
+ container.getRequiredInterfaces().get(0).setProvider(provided);
+
+ Scope external = new DefaultScope(new ProvidedInterface[0]);
+ external.publishInterface(provided, 100);
+
+ container.start(external);
+ }
+
+ public void testProvidedInterfaces() {
+ Environment env = new Environment(tracker);
+ Container envcontainer = new Container("0").addComponent(env)
+ .addProvidedInterface(
+ new DefaultProvidedInterface("string", String.class))
+ .addProvidedInterface(
+ new DefaultProvidedInterface("integer", Integer.class));
+ Scope scope = envcontainer.start();
+
+ AssertionUtils.assertEquals(new String[] { "start.environment" },
+ tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+
+ envcontainer.stop(scope);
+ }
+
+ public void testCoupleTwoContainers() {
+ Environment env = new Environment(tracker);
+ Container envcontainer = new Container("0").addComponent(env)
+ .addProvidedInterface(
+ new DefaultProvidedInterface("string", String.class))
+ .addProvidedInterface(
+ new DefaultProvidedInterface("integer", Integer.class));
+
+ Application app = new Application(tracker);
+ Container appcontainer = new Container("1").addComponent(app)
+ .addRequiredInterface(
+ new DefaultRequiredInterface("string", String.class))
+ .addRequiredInterface(
+ new DefaultRequiredInterface("integer", Integer.class));
+
+ Container top = new Container("top");
+ top.addComponent(envcontainer).addComponent(appcontainer);
+
+ top.start();
+ AssertionUtils.assertEquals(new String[] { "start.environment",
+ "start.application" }, tracker.getEvents(Thread.currentThread())
+ .toArray(new String[0]));
+ }
+
+ public void testNonUniqueRequiredInterface() {
+ final Container container = new Container("top");
+ container.addRequiredInterface(new DefaultRequiredInterface("i",
+ Integer.class));
+ container.addRequiredInterface(new DefaultRequiredInterface("x",
+ String.class));
+ container.addRequiredInterface(new DefaultRequiredInterface("y",
+ String.class));
+
+ Application app = new Application("1");
+ container.addComponent(app);
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.start();
+ }
+ }, SystemAssemblyException.class);
+
+ container.connectExternalRequired("1", app.getRequiredInterfaces().get(
+ 0).getName(), "y");
+
+ ProvidedInterface i = new DefaultProvidedInterface("i", Integer.class);
+ ProvidedInterface x = new DefaultProvidedInterface("x", String.class);
+ ProvidedInterface y = new DefaultProvidedInterface("y", String.class);
+
+ Scope externalScope = new DefaultScope(new ProvidedInterface[0]);
+
+ externalScope.publishInterface(i, 100);
+ externalScope.publishInterface(x, "x-value");
+ externalScope.publishInterface(y, "y-value");
+
+ container.getRequiredInterfaces().get(0).setProvider(i);
+ container.getRequiredInterfaces().get(1).setProvider(x);
+ container.getRequiredInterfaces().get(2).setProvider(y);
+
+ container.start(externalScope);
+
+ assertEquals("y-value", app.getString());
+ }
+
+ public void testNonUniqueRequiredInterfaceWrongNames() {
+ final Container container = new Container("top");
+ container.addRequiredInterface(new DefaultRequiredInterface("i",
+ Integer.class));
+ container.addRequiredInterface(new DefaultRequiredInterface("x",
+ String.class));
+ container.addRequiredInterface(new DefaultRequiredInterface("y",
+ String.class));
+
+ final Application app = new Application("1");
+ container.addComponent(app);
+
+ // wrong component name.
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalRequired("2", "x", "y");
+ }
+ }, SystemAssemblyException.class);
+
+ // Wrong interface name of component.
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalRequired("1", app
+ .getRequiredInterfaces().get(0).getName() +
+ "xxx", "y");
+ }
+ }, SystemAssemblyException.class);
+
+ // Wrong external interface name of container
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalRequired("1", app
+ .getRequiredInterfaces().get(0).getName(), "z");
+ }
+ }, SystemAssemblyException.class);
+ }
+
+ public void testNonUniqueProvidedInterface() {
+ final Container container = new Container("top")
+ .addProvidedInterface(new DefaultProvidedInterface("external",
+ String.class));
+ Environment env1 = new Environment("env1");
+ Environment env2 = new Environment("env2");
+
+ container.addComponent(env1);
+ container.addComponent(env2);
+
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.start();
+ }
+ }, SystemAssemblyException.class);
+
+ // now choose env2
+ container.connectExternalProvided(container.getProvidedInterfaces()
+ .get(0).getName(), env2.getName(), env2.getProvidedInterfaces()
+ .get(0).getName());
+
+ Scope scope = container.start();
+
+ // check the value of the provided interface of the container
+ String value = scope.getInterfaceImplementation(container
+ .getProvidedInterfaces().get(0), String.class);
+ assertNotNull(value);
+ assertEquals(value, env2.getString());
+ assertFalse(value.equals(env1.getString()));
+ }
+
+ public void testNonUniqueProvidedInterfaceWrongNames() {
+ final Container container = new Container("top")
+ .addProvidedInterface(new DefaultProvidedInterface("external",
+ String.class));
+ final Environment env1 = new Environment("env1");
+ final Environment env2 = new Environment("env2");
+
+ container.addComponent(env1);
+ container.addComponent(env2);
+
+ // Wrong external provided interface name
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container
+ .connectExternalProvided(container.getProvidedInterfaces()
+ .get(0).getName() +
+ "xx", "env1", env1.getProvidedInterfaces().get(0)
+ .getName());
+ }
+ }, SystemAssemblyException.class);
+
+ // Wrong provided interface name.
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalProvided(container
+ .getProvidedInterfaces().get(0).getName(), "env1", env1
+ .getProvidedInterfaces().get(0).getName() +
+ "xx");
+ }
+ }, SystemAssemblyException.class);
+
+ // Wrong provided component
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ @Override
+ public void run() throws Exception {
+ container.connectExternalProvided(container
+ .getProvidedInterfaces().get(0).getName(), "env3", env1
+ .getProvidedInterfaces().get(0).getName());
+ }
+ }, SystemAssemblyException.class);
+ }
+
+ private static class MyMultiple implements Serializable, Runnable {
+ @Override
+ public void run() {
+ // Empty
+ }
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
import junit.framework.TestCase;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class AbstractComponentTest extends TestCase {
+ public void testNotAllInterfacesStarted() {
+ try {
+ Component<?> component = new AbstractComponent<Object>("xx",
+ new ProvidedInterface[] { new DefaultProvidedInterface("xxx",
+ String.class) }, new RequiredInterface[0]) {
+ @Override
+ protected Object doStart(Scope aScope) {
+ // Empty, not starting service.
+ return null;
+ }
- public void testNotAllInterfacesStarted() {
- try {
- Component<?> component = new AbstractComponent<Object>("xx",
- new ProvidedInterface[] { new DefaultProvidedInterface(
- "xxx", String.class) }, new RequiredInterface[0]) {
- @Override
- protected Object doStart(Scope aScope) {
- // Empty, not starting service.
- return null;
- }
+ @Override
+ protected void doStop(Object aRuntime) {
+ // Empty.
+ }
+ };
+
+ component
+ .start(new DefaultScope(component.getProvidedInterfaces()));
+ } catch (SystemAssemblyException e) {
+ // e.printStackTrace();
+ return;
+ }
- @Override
- protected void doStop(Object aRuntime) {
- // Empty.
- }
- };
- component.start(new DefaultScope(component.getProvidedInterfaces()));
- } catch (SystemAssemblyException e) {
- //e.printStackTrace();
- return;
- }
- fail();
- }
-
- public void testUnexpectedServicesStarted() {
- try {
+ fail();
+ }
+
+ public void testUnexpectedServicesStarted() {
+ try {
Component<?> component = new AbstractComponent<Object>("xx",
- new ProvidedInterface[0], new RequiredInterface[0]) {
+ new ProvidedInterface[0], new RequiredInterface[0]) {
@Override
protected Object doStart(Scope aScope) {
- addInterface(new DefaultProvidedInterface("x", Integer.class), 100, aScope);
- return null;
+ addInterface(new DefaultProvidedInterface("x",
+ Integer.class), 100, aScope);
+
+ return null;
}
@Override
// Empty.
}
};
- component.start(new DefaultScope(component.getProvidedInterfaces()));
+
+ component
+ .start(new DefaultScope(component.getProvidedInterfaces()));
} catch (SystemAssemblyException e) {
- //e.printStackTrace();
+ // e.printStackTrace();
return;
}
+
fail();
- }
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.core;
-import java.io.Serializable;
+import junit.framework.TestCase;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.DefaultRequiredInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
-import junit.framework.TestCase;
+import java.io.Serializable;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultInterfaceDescriptorTest extends TestCase {
+ public void testOneRequiredOneProvidedMatch() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ String.class);
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ String.class);
+ assertTrue(required.implementedBy(provided));
+ }
+
+ public void testOneRequiredOneProvidedMatchSubClass() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ Integer.class);
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ Number.class);
+ assertTrue(required.implementedBy(provided));
+ }
+
+ public void testOneRequiredOneProvidedNoMatch() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ String.class);
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ Number.class);
+ assertFalse(required.implementedBy(provided));
+ }
+
+ public void testOneRequiredMultipleProvidedMatch() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ new Class[] { String.class, Integer.class });
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ String.class);
+ assertTrue(required.implementedBy(provided));
+ }
+
+ public void testMultipleRequiredOneProvidedMatch() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ MyMultiple.class);
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ new Class[] { Runnable.class, Serializable.class });
+ assertTrue(required.implementedBy(provided));
+ }
+
+ public void testMultipleRequiredOneProvidedNoMatch() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ MyMultiple.class);
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ new Class[] { String.class, Runnable.class });
+ assertFalse(required.implementedBy(provided));
+ }
+
+ public void testMultipleRequiredMultipleProvidedMatch() {
+ ProvidedInterface provided = new DefaultProvidedInterface("name",
+ new Class[] { Runnable.class, Serializable.class, String.class });
+ RequiredInterface required = new DefaultRequiredInterface("name",
+ new Class[] { Runnable.class, Serializable.class });
+ assertTrue(required.implementedBy(provided));
+ }
+
+ public void testPrimitiveAndWrapperType() {
+ RequiredInterface req1 = new DefaultRequiredInterface("req1", int.class);
+ RequiredInterface req2 = new DefaultRequiredInterface("req1",
+ Integer.class);
+ ProvidedInterface prov1 = new DefaultProvidedInterface("prov1",
+ int.class);
+ ProvidedInterface prov2 = new DefaultProvidedInterface("prov2",
+ Integer.class);
+ assertTrue(req1.implementedBy(prov1));
+ assertTrue(req2.implementedBy(prov1));
+ assertTrue(req1.implementedBy(prov2));
+ assertTrue(req2.implementedBy(prov2));
+ }
- public void testOneRequiredOneProvidedMatch() {
- ProvidedInterface provided = new DefaultProvidedInterface("name", String.class);
- RequiredInterface required = new DefaultRequiredInterface("name", String.class);
- assertTrue(required.implementedBy(provided));
- }
-
- public void testOneRequiredOneProvidedMatchSubClass() {
- ProvidedInterface provided = new DefaultProvidedInterface("name", Integer.class);
- RequiredInterface required = new DefaultRequiredInterface("name", Number.class);
- assertTrue(required.implementedBy(provided));
- }
-
- public void testOneRequiredOneProvidedNoMatch() {
- ProvidedInterface provided = new DefaultProvidedInterface("name", String.class);
- RequiredInterface required = new DefaultRequiredInterface("name", Number.class);
- assertFalse(required.implementedBy(provided));
- }
-
- public void testOneRequiredMultipleProvidedMatch() {
- ProvidedInterface provided = new DefaultProvidedInterface("name",
- new Class[] { String.class, Integer.class} );
- RequiredInterface required = new DefaultRequiredInterface("name", String.class);
- assertTrue(required.implementedBy(provided));
- }
-
- private static class MyMultiple implements Runnable, Serializable {
- @Override
- public void run() {
- // Empty
- }
- }
-
- public void testMultipleRequiredOneProvidedMatch() {
- ProvidedInterface provided = new DefaultProvidedInterface("name",
- MyMultiple.class );
- RequiredInterface required = new DefaultRequiredInterface("name",
- new Class[] {Runnable.class, Serializable.class} );
- assertTrue(required.implementedBy(provided));
- }
-
- public void testMultipleRequiredOneProvidedNoMatch() {
- ProvidedInterface provided = new DefaultProvidedInterface("name",
- MyMultiple.class );
- RequiredInterface required = new DefaultRequiredInterface("name",
- new Class[] { String.class, Runnable.class} );
- assertFalse(required.implementedBy(provided));
- }
-
- public void testMultipleRequiredMultipleProvidedMatch() {
- ProvidedInterface provided = new DefaultProvidedInterface("name",
- new Class[] { Runnable.class, Serializable.class, String.class} );
- RequiredInterface required = new DefaultRequiredInterface("name",
- new Class[] {Runnable.class, Serializable.class} );
- assertTrue(required.implementedBy(provided));
- }
-
- public void testPrimitiveAndWrapperType() {
- RequiredInterface req1 = new DefaultRequiredInterface("req1", int.class);
- RequiredInterface req2 = new DefaultRequiredInterface("req1", Integer.class);
- ProvidedInterface prov1 = new DefaultProvidedInterface("prov1", int.class);
- ProvidedInterface prov2 = new DefaultProvidedInterface("prov2", Integer.class);
- assertTrue(req1.implementedBy(prov1));
- assertTrue(req2.implementedBy(prov1));
- assertTrue(req1.implementedBy(prov2));
- assertTrue(req2.implementedBy(prov2));
- }
-
+ private static class MyMultiple implements Runnable, Serializable {
+ @Override
+ public void run() {
+ // Empty
+ }
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
import junit.framework.TestCase;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultRequiredInterfaceTest extends TestCase {
-
public void testEquals() {
assertFalse(new DefaultRequiredInterface("a", String.class)
- .equals(new DefaultRequiredInterface("a", String.class)));
+ .equals(new DefaultRequiredInterface("a", String.class)));
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import junit.framework.TestCase;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultScopeTest extends TestCase {
-
- public void testLookup() {
- ProvidedInterface provider = new DefaultProvidedInterface("x", Integer.class);
- Scope scope = new DefaultScope(new ProvidedInterface[0]);
-
+ public void testLookup() {
+ ProvidedInterface provider = new DefaultProvidedInterface("x",
+ Integer.class);
+ Scope scope = new DefaultScope(new ProvidedInterface[0]);
+
scope.publishInterface(provider, 100);
- assertEquals(100, scope.getInterfaceImplementation(provider, Integer.class).intValue());
+ assertEquals(100, scope.getInterfaceImplementation(provider,
+ Integer.class).intValue());
}
-
- public void testNestedLookup() {
- ProvidedInterface provider1 = new DefaultProvidedInterface("x", Integer.class);
+
+ public void testNestedLookup() {
+ ProvidedInterface provider1 = new DefaultProvidedInterface("x",
+ Integer.class);
Scope parent = new DefaultScope(new ProvidedInterface[0]);
-
+
parent.publishInterface(provider1, 100);
-
- ProvidedInterface provider2 = new DefaultProvidedInterface("y", String.class);
+
+ ProvidedInterface provider2 = new DefaultProvidedInterface("y",
+ String.class);
Scope child = new DefaultScope(new ProvidedInterface[0], parent);
-
+
child.publishInterface(provider2, "hallo");
-
+
assertFalse(provider1.equals(provider2));
-
- assertEquals(100, child.getInterfaceImplementation(provider1, Integer.class).intValue());
- assertEquals("hallo", child.getInterfaceImplementation(provider2, String.class));
- }
+ assertEquals(100, child.getInterfaceImplementation(provider1,
+ Integer.class).intValue());
+ assertEquals("hallo", child.getInterfaceImplementation(provider2,
+ String.class));
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
-import javax.sql.DataSource;
-
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
+
import org.wamblee.test.EventTracker;
+import javax.sql.DataSource;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class Environment extends AbstractComponent<Object> {
+ private static int COUNT = 0;
+
+ private EventTracker<String> tracker;
+
+ private double random;
+
+ private int integer;
- private static final ProvidedInterface[] provided(String aPrefix) {
- return new ProvidedInterface[] {
- new DefaultProvidedInterface(aPrefix + "datasource", String.class),
- new DefaultProvidedInterface(aPrefix + "integer", Integer.class) };
- }
-
- private static int COUNT = 0;
-
- private EventTracker<String> _tracker;
- private double _random;
- private int _integer;
-
- public Environment() {
- this("environment");
- }
-
- public Environment(String aName) {
- this(aName, "");
+ /**
+ * Creates a new Environment object.
+ */
+ public Environment() {
+ this("environment");
}
-
- public Environment(String aName, String aPrefix) {
+
+ /**
+ * Creates a new Environment object.
+ *
+ */
+ public Environment(String aName) {
+ this(aName, "");
+ }
+
+ /**
+ * Creates a new Environment object.
+ *
+ */
+ public Environment(String aName, String aPrefix) {
super(aName, provided(aPrefix), new RequiredInterface[0]);
- _random = Math.random();
- _integer = COUNT++;
+ random = Math.random();
+ integer = COUNT++;
}
+ /**
+ * Creates a new Environment object.
+ *
+ */
+ public Environment(EventTracker aTracker) {
+ this();
+ tracker = aTracker;
+ }
+
+ private static final ProvidedInterface[] provided(String aPrefix) {
+ return new ProvidedInterface[] {
+ new DefaultProvidedInterface(aPrefix + "datasource", String.class),
+ new DefaultProvidedInterface(aPrefix + "integer", Integer.class) };
+ }
+
+ public Integer getInteger() {
+ return integer;
+ }
+
+ public String getString() {
+ return getName() + ".hello";
+ }
+ @Override
+ protected Object doStart(Scope aScope) {
+ addInterface(getProvidedInterfaces().get(0), getString(), aScope);
+ addInterface(getProvidedInterfaces().get(1), getInteger(), aScope);
+ track("start." + getName());
- public Environment(EventTracker aTracker) {
- this();
- _tracker = aTracker;
- }
-
- public Integer getInteger() {
- return _integer;
- }
-
- public String getString() {
- return getName() + ".hello";
- }
-
- @Override
- protected Object doStart(Scope aScope) {
- addInterface(getProvidedInterfaces().get(0), getString(), aScope);
- addInterface(getProvidedInterfaces().get(1), getInteger(), aScope);
- track("start." + getName());
- return _random;
- }
-
- @Override
- protected void doStop(Object aRuntime) {
- track("stop." + getName());
- if (_random != (Double) aRuntime) {
- throw new IllegalArgumentException("Wrong runtime: expected "
- + _random + " but got " + aRuntime);
- }
- }
-
- private void track(String aString) {
- if (_tracker == null) {
- return;
- }
- _tracker.eventOccurred(aString);
- }
+ return random;
+ }
+
+ @Override
+ protected void doStop(Object aRuntime) {
+ track("stop." + getName());
+
+ if (random != (Double) aRuntime) {
+ throw new IllegalArgumentException("Wrong runtime: expected " +
+ random + " but got " + aRuntime);
+ }
+ }
+
+ private void track(String aString) {
+ if (tracker == null) {
+ return;
+ }
+
+ tracker.eventOccurred(aString);
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
-import javax.sql.DataSource;
-
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
+
import org.wamblee.test.EventTracker;
+import javax.sql.DataSource;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class IntegerComponent extends AbstractComponent<Object> {
+ private EventTracker<String> tracker;
- private static final ProvidedInterface[] provided(String aPrefix) {
- return new ProvidedInterface[] {
- new DefaultProvidedInterface(aPrefix + "integer", Integer.class) };
- }
+ private double random;
- private EventTracker<String> _tracker;
- private double _random;
+ /**
+ * Creates a new IntegerComponent object.
+ */
+ public IntegerComponent() {
+ this("environment");
+ }
- public IntegerComponent() {
- this("environment");
- }
-
- public IntegerComponent(String aName) {
- this(aName, "");
+ /**
+ * Creates a new IntegerComponent object.
+ *
+ */
+ public IntegerComponent(String aName) {
+ this(aName, "");
}
-
- public IntegerComponent(String aName, String aPrefix) {
+
+ /**
+ * Creates a new IntegerComponent object.
+ *
+ */
+ public IntegerComponent(String aName, String aPrefix) {
super(aName, provided(aPrefix), new RequiredInterface[0]);
- _random = Math.random();
+ random = Math.random();
+ }
+
+ /**
+ * Creates a new IntegerComponent object.
+ *
+ */
+ public IntegerComponent(EventTracker aTracker) {
+ this();
+ tracker = aTracker;
+ }
+
+ private static final ProvidedInterface[] provided(String aPrefix) {
+ return new ProvidedInterface[] { new DefaultProvidedInterface(aPrefix +
+ "integer", Integer.class) };
}
+ public Integer getInteger() {
+ return 2;
+ }
+
+ @Override
+ protected Object doStart(Scope aScope) {
+ addInterface(getProvidedInterfaces().get(1), getInteger(), aScope);
+ track("start." + getName());
+ return random;
+ }
- public IntegerComponent(EventTracker aTracker) {
- this();
- _tracker = aTracker;
- }
-
- public Integer getInteger() {
- return 2;
- }
-
- @Override
- protected Object doStart(Scope aScope) {
- addInterface(getProvidedInterfaces().get(1), getInteger(), aScope);
- track("start." + getName());
- return _random;
- }
-
- @Override
- protected void doStop(Object aRuntime) {
- track("stop." + getName());
- if (_random != (Double) aRuntime) {
- throw new IllegalArgumentException("Wrong runtime: expected "
- + _random + " but got " + aRuntime);
- }
- }
-
- private void track(String aString) {
- if (_tracker == null) {
- return;
- }
- _tracker.eventOccurred(aString);
- }
+ @Override
+ protected void doStop(Object aRuntime) {
+ track("stop." + getName());
+
+ if (random != (Double) aRuntime) {
+ throw new IllegalArgumentException("Wrong runtime: expected " +
+ random + " but got " + aRuntime);
+ }
+ }
+
+ private void track(String aString) {
+ if (tracker == null) {
+ return;
+ }
+
+ tracker.eventOccurred(aString);
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.core;
+import java.io.Serializable;
import java.util.Comparator;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class RequiredInterfaceComparator implements
- Comparator<RequiredInterface> {
+ Comparator<RequiredInterface>, Serializable {
+
+ private static final long serialVersionUID = 7631587103378238574L;
@Override
public int compare(RequiredInterface aO1, RequiredInterface aO2) {
return aO1.getName().compareTo(aO2.getName());
}
-
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.core;
-import javax.sql.DataSource;
-
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
+
import org.wamblee.test.EventTracker;
+import javax.sql.DataSource;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class StringComponent extends AbstractComponent<Object> {
+ private EventTracker<String> tracker;
- private static final ProvidedInterface[] provided(String aPrefix) {
- return new ProvidedInterface[] {
- new DefaultProvidedInterface(aPrefix + "datasource", String.class) };
- }
+ private double random;
- private EventTracker<String> _tracker;
- private double _random;
+ /**
+ * Creates a new StringComponent object.
+ */
+ public StringComponent() {
+ this("environment");
+ }
- public StringComponent() {
- this("environment");
- }
-
- public StringComponent(String aName) {
- this(aName, "");
+ /**
+ * Creates a new StringComponent object.
+ *
+ */
+ public StringComponent(String aName) {
+ this(aName, "");
}
-
- public StringComponent(String aName, String aPrefix) {
+
+ /**
+ * Creates a new StringComponent object.
+ *
+ */
+ public StringComponent(String aName, String aPrefix) {
super(aName, provided(aPrefix), new RequiredInterface[0]);
- _random = Math.random();
+ random = Math.random();
+ }
+
+ /**
+ * Creates a new StringComponent object.
+ *
+ */
+ public StringComponent(EventTracker aTracker) {
+ this();
+ tracker = aTracker;
}
+ private static final ProvidedInterface[] provided(String aPrefix) {
+ return new ProvidedInterface[] { new DefaultProvidedInterface(aPrefix +
+ "datasource", String.class) };
+ }
+
+ public Integer getInteger() {
+ return 2;
+ }
+
+ public String getString() {
+ return getName() + ".hello";
+ }
+
+ @Override
+ protected Object doStart(Scope aScope) {
+ addInterface(getProvidedInterfaces().get(0), getString(), aScope);
+ track("start." + getName());
+ return random;
+ }
+
+ @Override
+ protected void doStop(Object aRuntime) {
+ track("stop." + getName());
+
+ if (random != (Double) aRuntime) {
+ throw new IllegalArgumentException("Wrong runtime: expected " +
+ random + " but got " + aRuntime);
+ }
+ }
+
+ private void track(String aString) {
+ if (tracker == null) {
+ return;
+ }
- public StringComponent(EventTracker aTracker) {
- this();
- _tracker = aTracker;
- }
-
- public Integer getInteger() {
- return 2;
- }
-
- public String getString() {
- return getName() + ".hello";
- }
-
- @Override
- protected Object doStart(Scope aScope) {
- addInterface(getProvidedInterfaces().get(0), getString(), aScope);
- track("start." + getName());
- return _random;
- }
-
- @Override
- protected void doStop(Object aRuntime) {
- track("stop." + getName());
- if (_random != (Double) aRuntime) {
- throw new IllegalArgumentException("Wrong runtime: expected "
- + _random + " but got " + aRuntime);
- }
- }
-
- private void track(String aString) {
- if (_tracker == null) {
- return;
- }
- _tracker.eventOccurred(aString);
- }
+ tracker.eventOccurred(aString);
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph;
+import junit.framework.TestCase;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
-import junit.framework.TestCase;
import org.wamblee.system.container.Application;
import org.wamblee.system.core.Component;
import org.wamblee.system.graph.component.ProvidedInterfaceNode;
import org.wamblee.system.graph.component.RequiredInterfaceNode;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class CompositeEdgeFilterTest extends TestCase {
- private Application _app = new Application();
- private Environment _env = new Environment();
-
- private Edge createEdge(Component aClient, RequiredInterface aRequired,
- Component aServer, ProvidedInterface aProvided) {
+ private Application app = new Application();
+
+ private Environment env = new Environment();
+
+ private Edge createEdge(Component aClient, RequiredInterface aRequired,
+ Component aServer, ProvidedInterface aProvided) {
Node from = new RequiredInterfaceNode(aClient, aRequired);
Node to = new ProvidedInterfaceNode(aServer, aProvided);
+
return new DefaultEdge(from, to);
}
- public void testEmpty() {
- EdgeFilter restriction = new CompositeEdgeFilter();
- assertFalse(restriction.isViolated(createEdge(_app, _app.getRequiredInterfaces().get(0),
- _env, _env.getProvidedInterfaces().get(0))));
+ public void testEmpty() {
+ EdgeFilter restriction = new CompositeEdgeFilter();
+ assertFalse(restriction.isViolated(createEdge(app, app
+ .getRequiredInterfaces().get(0), env, env.getProvidedInterfaces()
+ .get(0))));
}
-
- private void configureRestriction(EdgeFilter base, boolean aResult) {
- stub(base.isViolated((Edge)anyObject())).toReturn(aResult);
+
+ private void configureRestriction(EdgeFilter aBase, boolean aResult) {
+ stub(aBase.isViolated((Edge) anyObject())).toReturn(aResult);
}
-
- public void testOneRestriction() {
+
+ public void testOneRestriction() {
EdgeFilter base = mock(EdgeFilter.class);
CompositeEdgeFilter composite = new CompositeEdgeFilter();
composite.add(base);
-
- // First let the base return false and verify the result.
-
+
+ // First let the base return false and verify the result.
configureRestriction(base, false);
-
- assertFalse(composite.isViolated(createEdge(_app, _app.getRequiredInterfaces().get(0),
- _env, _env.getProvidedInterfaces().get(0))));
-
+
+ assertFalse(composite.isViolated(createEdge(app, app
+ .getRequiredInterfaces().get(0), env, env.getProvidedInterfaces()
+ .get(0))));
+
// Second let the base return true and verify the result.
configureRestriction(base, true);
-
- assertTrue(composite.isViolated(createEdge(_app, _app.getRequiredInterfaces().get(0),
- _env, _env.getProvidedInterfaces().get(0))));
+
+ assertTrue(composite.isViolated(createEdge(app, app
+ .getRequiredInterfaces().get(0), env, env.getProvidedInterfaces()
+ .get(0))));
}
-
-
- public void testTwoRestrictions() {
+ public void testTwoRestrictions() {
EdgeFilter base1 = mock(EdgeFilter.class);
CompositeEdgeFilter composite = new CompositeEdgeFilter();
composite.add(base1);
+
EdgeFilter base2 = mock(EdgeFilter.class);
composite.add(base2);
-
- // 1. base1 not violated and base 2 not violated -> not violated.
-
+
+ // 1. base1 not violated and base 2 not violated -> not violated.
configureRestriction(base1, false);
configureRestriction(base2, false);
- assertFalse(composite.isViolated(createEdge(_app, _app.getRequiredInterfaces().get(0),
- _env, _env.getProvidedInterfaces().get(0))));
-
+ assertFalse(composite.isViolated(createEdge(app, app
+ .getRequiredInterfaces().get(0), env, env.getProvidedInterfaces()
+ .get(0))));
+
// 2. base 1 not violated but base 2 violated -> violated
configureRestriction(base1, false);
configureRestriction(base2, true);
-
- assertTrue(composite.isViolated(createEdge(_app, _app.getRequiredInterfaces().get(0),
- _env, _env.getProvidedInterfaces().get(0))));
-
- // 3. base 1 violated -> violated and base 2 not called.
+
+ assertTrue(composite.isViolated(createEdge(app, app
+ .getRequiredInterfaces().get(0), env, env.getProvidedInterfaces()
+ .get(0))));
+
+ // 3. base 1 violated -> violated and base 2 not called.
configureRestriction(base1, true);
// base 2 should not be called.
-
- assertTrue(composite.isViolated(createEdge(_app, _app.getRequiredInterfaces().get(0),
- _env, _env.getProvidedInterfaces().get(0))));
+ assertTrue(composite.isViolated(createEdge(app, app
+ .getRequiredInterfaces().get(0), env, env.getProvidedInterfaces()
+ .get(0))));
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph;
-import java.util.Arrays;
-import java.util.List;
-
+import junit.framework.TestCase;
import static org.mockito.Mockito.*;
-import org.wamblee.test.AssertionUtils;
+import org.wamblee.test.AssertionUtils;
-import junit.framework.TestCase;
+import java.util.Arrays;
+import java.util.List;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class GraphTest extends TestCase {
-
public void testNodeMgt() {
final Graph graph = new Graph();
assertTrue(graph.getNodes().isEmpty());
assertTrue(graph.removeNode(x));
assertTrue(graph.getNodes().isEmpty());
- // Empty node set.
+ // Empty node set.
assertFalse(graph.removeNode(x));
-
- Node y = new DefaultNode("y");
- graph.addNodes(Arrays.asList(new Node[] { x, y} ));
+
+ Node y = new DefaultNode("y");
+ graph.addNodes(Arrays.asList(new Node[] { x, y }));
assertEquals(2, graph.getNodes().size());
-
+
// duplicate node
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
@Override
public void run() throws Exception {
- graph.addNode(new DefaultNode("x"));
+ graph.addNode(new DefaultNode("x"));
}
}, IllegalArgumentException.class);
}
- public void testEdgeMgt() {
+ public void testEdgeMgt() {
final Graph graph = new Graph();
- final Node x = new DefaultNode("x");
- final Node y = new DefaultNode("y");
+ final Node x = new DefaultNode("x");
+ final Node y = new DefaultNode("y");
graph.addNode(x);
graph.addNode(y);
- final Edge e = new DefaultEdge(x, y);
+
+ final Edge e = new DefaultEdge(x, y);
graph.addEdge(e);
assertEquals(Arrays.asList(new Edge[] { e }), graph.getEdges());
-
+
// duplicate edge.
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
@Override
public void run() throws Exception {
- graph.addEdge(e);
+ graph.addEdge(e);
}
}, IllegalArgumentException.class);
-
+
// Remove node when edge is still present
- AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+ AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
@Override
public void run() throws Exception {
graph.removeNode(x);
}
}, IllegalArgumentException.class);
-
-
+
Node a = new DefaultNode("a");
graph.addNode(a);
- graph.addEdges(Arrays.asList(new Edge[] { new DefaultEdge(x, a), new DefaultEdge(y, a) }));
+ graph.addEdges(Arrays.asList(new Edge[] { new DefaultEdge(x, a),
+ new DefaultEdge(y, a) }));
assertEquals(3, graph.getEdges().size());
}
-
- public void testExtend() {
- Graph graph = new Graph();
- graph.addNode(new MyNode("x", new String[] { "a", "b"}));
- graph.addNode(new MyNode("y", new String[] { "b", "c"}));
- graph.addNode(new MyNode("z", new String[] { "a", "c"}));
+
+ public void testExtend() {
+ Graph graph = new Graph();
+ graph.addNode(new MyNode("x", new String[] { "a", "b" }));
+ graph.addNode(new MyNode("y", new String[] { "b", "c" }));
+ graph.addNode(new MyNode("z", new String[] { "a", "c" }));
graph.extend(new MyEdgeFactory());
-
- List<Edge> edges = graph.getEdges();
+
+ List<Edge> edges = graph.getEdges();
assertEquals(12, edges.size()); // 2 outgoing and 2 incoming nodes.
}
-
- public void testApplyFilter() {
- Graph graph = new Graph();
+
+ public void testApplyFilter() {
+ Graph graph = new Graph();
graph.addNode(new DefaultNode("x"));
graph.addNode(new DefaultNode("y"));
graph.addNode(new DefaultNode("z"));
- graph.addEdge(new DefaultEdge(graph.findNode("x"), graph.findNode("y")));
- graph.addEdge(new DefaultEdge(graph.findNode("y"), graph.findNode("z")));
- graph.addEdge(new DefaultEdge(graph.findNode("z"), graph.findNode("x")));
-
+ graph
+ .addEdge(new DefaultEdge(graph.findNode("x"), graph.findNode("y")));
+ graph
+ .addEdge(new DefaultEdge(graph.findNode("y"), graph.findNode("z")));
+ graph
+ .addEdge(new DefaultEdge(graph.findNode("z"), graph.findNode("x")));
+
assertEquals(3, graph.getEdges().size());
-
- graph.applyFilter(new EdgeFilter() {
+
+ graph.applyFilter(new EdgeFilter() {
@Override
public boolean isViolated(Edge aEdge) {
- if (aEdge.getFrom().getName().equals("x")) {
- return false;
+ if (aEdge.getFrom().getName().equals("x")) {
+ return false;
}
- return true;
+
+ return true;
}
- });
-
+ });
+
assertEquals(1, graph.getEdges().size());
assertEquals("x", graph.getEdges().get(0).getFrom().getName());
-
}
-
- public void testFindIncomingOutgoing() {
+
+ public void testFindIncomingOutgoing() {
Graph graph = new Graph();
Node x = new DefaultNode("x");
- Node y = new DefaultNode("y");
+ Node y = new DefaultNode("y");
graph.addNode(x);
graph.addNode(y);
- Edge e = new DefaultEdge(x,y);
+
+ Edge e = new DefaultEdge(x, y);
graph.addEdge(e);
-
+
List<Edge> incoming = graph.findIncoming(x);
- assertTrue(incoming.isEmpty());
+ assertTrue(incoming.isEmpty());
+
List<Edge> outgoing = graph.findOutgoing(x);
assertEquals(1, outgoing.size());
assertSame(e, outgoing.get(0));
-
+
incoming = graph.findIncoming(y);
assertEquals(1, incoming.size());
assertSame(e, incoming.get(0));
-
+
outgoing = graph.findOutgoing(y);
- assertTrue(outgoing.isEmpty());
+ assertTrue(outgoing.isEmpty());
}
-
+
public void testAccept() {
- Graph graph = new Graph();
- Node x = new DefaultNode("x");
- Node y = new DefaultNode("y");
+ Graph graph = new Graph();
+ Node x = new DefaultNode("x");
+ Node y = new DefaultNode("y");
Edge e = new DefaultEdge(x, y);
graph.addNode(x);
graph.addNode(y);
graph.addEdge(e);
- Visitor visitor = mock(Visitor.class);
-
+
+ Visitor visitor = mock(Visitor.class);
+
graph.accept(visitor);
verify(visitor).visitNode(x);
verify(visitor).visitNode(y);
verify(visitor).visitEdge(e);
-
+
verifyNoMoreInteractions(visitor);
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.ArrayList;
import java.util.List;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class MyEdgeFactory implements EdgeFactory<MyNode> {
-
- public MyEdgeFactory() {
+ /**
+ * Creates a new MyEdgeFactory object.
+ */
+ public MyEdgeFactory() {
// Empty.
}
@Override
public List<Edge> create(MyNode aFrom, MyNode aTo) {
List<Edge> result = new ArrayList<Edge>();
- for (String fromPort: aFrom.getPorts()) {
- for (String toPort: aTo.getPorts()) {
- if ( fromPort.equals(toPort)) {
+
+ for (String fromPort : aFrom.getPorts()) {
+ for (String toPort : aTo.getPorts()) {
+ if (fromPort.equals(toPort)) {
result.add(new DefaultEdge(aFrom, aTo));
}
}
}
-
- return result;
- }
+ return result;
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph;
+import java.util.Arrays;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class MyNode extends DefaultNode {
+ private String[] ports;
- private String[] _ports;
-
+ /**
+ * Creates a new MyNode object.
+ *
+ */
public MyNode(String aName, String[] aPorts) {
super(aName);
- _ports = aPorts;
+ ports = Arrays.copyOf(aPorts, aPorts.length);
}
-
+
public String[] getPorts() {
- return _ports;
+ return Arrays.copyOf(ports, ports.length);
+ }
+
+ @Override
+ public boolean equals(Object aObj) {
+ if (!super.equals(aObj)) {
+ return false;
+ }
+ if (!(aObj instanceof MyNode)) {
+ return false;
+ }
+ return Arrays.equals(ports, ((MyNode) aObj).ports);
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
import junit.framework.TestCase;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.EdgeFilter;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ConnectExternalProvidedProvidedEdgeFilterTest extends TestCase {
+ private Container container;
+
+ private Component<Object> internal;
+
+ private String externalInterfaceName;
+
+ private String internalComponentName;
+
+ private String internalInterfaceName;
- private Container _container;
- private Component<Object> _internal;
- private String _externalInterfaceName;
- private String _internalComponentName;
- private String _internalInterfaceName;
- private Edge _edge;
+ private Edge edge;
@Override
protected void setUp() throws Exception {
- _container = new Container("container")
- .addProvidedInterface(new DefaultProvidedInterface("string",
- String.class));
- _internal = new Environment("env1");
-
- _externalInterfaceName = _container.getProvidedInterfaces().get(0)
- .getName();
- _internalComponentName = _internal.getName();
- _internalInterfaceName = _internal.getProvidedInterfaces().get(0).getName();
-
- _edge = new DefaultEdge(new ExternalProvidedInterfaceNode(_container,
- _container.getProvidedInterfaces().get(0)),
- new ProvidedInterfaceNode(_internal, _internal
- .getProvidedInterfaces().get(0)));
+ container = new Container("container")
+ .addProvidedInterface(new DefaultProvidedInterface("string",
+ String.class));
+ internal = new Environment("env1");
+
+ externalInterfaceName = container.getProvidedInterfaces().get(0)
+ .getName();
+ internalComponentName = internal.getName();
+ internalInterfaceName = internal.getProvidedInterfaces().get(0)
+ .getName();
+
+ edge = new DefaultEdge(new ExternalProvidedInterfaceNode(container,
+ container.getProvidedInterfaces().get(0)),
+ new ProvidedInterfaceNode(internal, internal
+ .getProvidedInterfaces().get(0)));
}
public void testWrongExternal() {
EdgeFilter filter = new ConnectExternalProvidedProvidedFilter(
- _externalInterfaceName + "x", _internalComponentName,
- _internalInterfaceName);
- assertFalse(filter.isViolated(_edge));
+ externalInterfaceName + "x", internalComponentName,
+ internalInterfaceName);
+ assertFalse(filter.isViolated(edge));
}
public void testRightExternalWrongComponent() {
EdgeFilter filter = new ConnectExternalProvidedProvidedFilter(
- _externalInterfaceName, _internalComponentName + "x",
- _internalInterfaceName);
- assertTrue(filter.isViolated(_edge));
+ externalInterfaceName, internalComponentName + "x",
+ internalInterfaceName);
+ assertTrue(filter.isViolated(edge));
}
public void testRightExternalWrongInternal() {
EdgeFilter filter = new ConnectExternalProvidedProvidedFilter(
- _externalInterfaceName, _internalComponentName,
- _internalInterfaceName + "x");
- assertTrue(filter.isViolated(_edge));
+ externalInterfaceName, internalComponentName,
+ internalInterfaceName + "x");
+ assertTrue(filter.isViolated(edge));
}
-
- public void testEverythingRight() {
+
+ public void testEverythingRight() {
EdgeFilter filter = new ConnectExternalProvidedProvidedFilter(
- _externalInterfaceName, _internalComponentName,
- _internalInterfaceName);
- assertFalse(filter.isViolated(_edge));
+ externalInterfaceName, internalComponentName, internalInterfaceName);
+ assertFalse(filter.isViolated(edge));
}
-
public void testWrongEdgeType() {
EdgeFilter filter = new ConnectExternalProvidedProvidedFilter(
- _externalInterfaceName, _internalComponentName,
- _internalInterfaceName);
+ externalInterfaceName, internalComponentName, internalInterfaceName);
DefaultEdge edge = new DefaultEdge(new DefaultNode("x"),
- new DefaultNode("y"));
+ new DefaultNode("y"));
assertFalse(filter.isViolated(edge));
}
-
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.graph.component;
import junit.framework.TestCase;
import org.wamblee.system.graph.EdgeFilter;
import org.wamblee.system.graph.Node;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ConnectRequiredExternallyRequiredEdgeFilterTest extends TestCase {
+ private Component<?> comp;
+
+ private Container container;
- private Component<?> _comp;
- private Container _container;
- private Edge _edge;
+ private Edge edge;
@Override
protected void setUp() throws Exception {
- _comp = new Application();
- _container = new Container("container")
- .addRequiredInterface(new DefaultRequiredInterface("x",
- String.class));
- Node req = new RequiredInterfaceNode(_comp, _comp
- .getRequiredInterfaces().get(0));
- Node external = new ExternalRequiredInterfaceNode(_container,
- _container.getRequiredInterfaces().get(0));
- _edge = new DefaultEdge(req, external);
+ comp = new Application();
+ container = new Container("container")
+ .addRequiredInterface(new DefaultRequiredInterface("x",
+ String.class));
+
+ Node req = new RequiredInterfaceNode(comp, comp.getRequiredInterfaces()
+ .get(0));
+ Node external = new ExternalRequiredInterfaceNode(container, container
+ .getRequiredInterfaces().get(0));
+ edge = new DefaultEdge(req, external);
}
public void testRightComponentRightInterface() {
EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
- _comp.getName(), _comp.getRequiredInterfaces().get(0).getName(),
- _container.getRequiredInterfaces().get(0).getName());
- assertFalse(filter.isViolated(_edge));
+ comp.getName(), comp.getRequiredInterfaces().get(0).getName(),
+ container.getRequiredInterfaces().get(0).getName());
+ assertFalse(filter.isViolated(edge));
}
public void testWrongInterface() {
EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
- _comp.getName(), _comp.getRequiredInterfaces().get(0).getName()
- + "xx", _container.getRequiredInterfaces().get(0).getName());
- assertFalse(filter.isViolated(_edge));
+ comp.getName(), comp.getRequiredInterfaces().get(0).getName() +
+ "xx", container.getRequiredInterfaces().get(0).getName());
+ assertFalse(filter.isViolated(edge));
}
public void testWrongComponent() {
EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
- _comp.getName() + "xx", _comp.getRequiredInterfaces().get(0)
- .getName(), _container.getRequiredInterfaces().get(0)
- .getName());
- assertFalse(filter.isViolated(_edge));
+ comp.getName() + "xx", comp.getRequiredInterfaces().get(0)
+ .getName(), container.getRequiredInterfaces().get(0).getName());
+ assertFalse(filter.isViolated(edge));
}
public void testWrongExternalInterface() {
EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
- _comp.getName(), _comp.getRequiredInterfaces().get(0).getName(),
- _container.getRequiredInterfaces().get(0).getName() + "xx");
- assertTrue(filter.isViolated(_edge));
+ comp.getName(), comp.getRequiredInterfaces().get(0).getName(),
+ container.getRequiredInterfaces().get(0).getName() + "xx");
+ assertTrue(filter.isViolated(edge));
}
public void testWrongEdgeType() {
DefaultEdge edge = new DefaultEdge(new DefaultNode("x"),
- new DefaultNode("y"));
+ new DefaultNode("y"));
EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
- _comp.getName(), _comp.getRequiredInterfaces().get(0).getName(),
- _container.getRequiredInterfaces().get(0).getName());
+ comp.getName(), comp.getRequiredInterfaces().get(0).getName(),
+ container.getRequiredInterfaces().get(0).getName());
assertFalse(filter.isViolated(edge));
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.graph.component;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import junit.framework.TestCase;
import org.wamblee.system.container.Application;
import org.wamblee.system.core.Environment;
import org.wamblee.system.graph.Edge;
import org.wamblee.system.graph.EdgeFilter;
import org.wamblee.system.graph.Node;
+
import org.wamblee.test.AssertionUtils;
-import junit.framework.TestCase;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ConnectRequiredProvidedEdgeFilterTest extends TestCase {
+ private Application app1 = new Application("app1", "pf1.");
- private Application _app1 = new Application("app1", "pf1.");
- private Application _app2 = new Application("app2", "pf2.");
-
- private Environment _env1 = new Environment("env1", "pf3.");
- private Environment _env2 = new Environment("env2", "pf4.");
-
-
- private void compare(Boolean[] aExpected, EdgeFilter aRestriction) {
- List<Boolean> result = new ArrayList<Boolean>();
-
-
-
- // order will be:
- // env1, app1
- // env1, app2
- // env2, app1
- // env2, app2
- for (Environment env: new Environment[] { _env1, _env2} ) {
- for (Application app: new Application[] { _app1, _app2} ) {
- Node from = new RequiredInterfaceNode(
- app, app.getRequiredInterfaces().get(0));
- Node to = new ProvidedInterfaceNode(
- env, env.getProvidedInterfaces().get(0));
- Edge edge = new DefaultEdge(from, to);
- result.add(aRestriction.isViolated(edge));
- }
- }
-
-
- assertEquals(Arrays.asList(aExpected), result);
+ private Application app2 = new Application("app2", "pf2.");
+
+ private Environment env1 = new Environment("env1", "pf3.");
+
+ private Environment env2 = new Environment("env2", "pf4.");
+
+ private void compare(Boolean[] aExpected, EdgeFilter aRestriction) {
+ List<Boolean> result = new ArrayList<Boolean>();
+
+ // order will be:
+ // env1, app1
+ // env1, app2
+ // env2, app1
+ // env2, app2
+ for (Environment env : new Environment[] { env1, env2 }) {
+ for (Application app : new Application[] { app1, app2 }) {
+ Node from = new RequiredInterfaceNode(app, app
+ .getRequiredInterfaces().get(0));
+ Node to = new ProvidedInterfaceNode(env, env
+ .getProvidedInterfaces().get(0));
+ Edge edge = new DefaultEdge(from, to);
+ result.add(aRestriction.isViolated(edge));
+ }
+ }
+
+ assertEquals(Arrays.asList(aExpected), result);
}
- public void testNoRestriction() {
+ public void testNoRestriction() {
AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
@Override
public void run() throws Exception {
- EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter(null, null, null, null);
-
+ EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter(
+ null, null, null, null);
+ ignoredVariable(restriction);
}
}, IllegalArgumentException.class);
AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
@Override
public void run() throws Exception {
- EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter(null, null, "x", "y");
+ EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter(
+ null, null, "x", "y");
+ ignoredVariable(restriction);
}
}, IllegalArgumentException.class);
}
- public void testClientServer() {
- EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter("app1", null, "env1", null);
- compare(new Boolean[] { false, false, true, false}, restriction);
+ private static final void ignoredVariable(Object aObject) {
+ // for findbugs.
}
-
- public void testNoConnectionsAtAll() {
- EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter("app1", null, null, null);
- compare(new Boolean[] { true, false, true, false}, restriction);
+
+ public void testClientServer() {
+ EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter("app1",
+ null, "env1", null);
+ compare(new Boolean[] { false, false, true, false }, restriction);
}
-
- public void testExplicitConfig() {
- _app1 = new Application("app1");
- _app2 = new Application("app2");
- _env1 = new Environment("env1");
- _env2 = new Environment("env2");
-
- EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter(
- "app2", "string", "env1", "datasource");
- compare(new Boolean[] { false, false, false, true}, restriction);
-
+
+ public void testNoConnectionsAtAll() {
+ EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter("app1",
+ null, null, null);
+ compare(new Boolean[] { true, false, true, false }, restriction);
+ }
+
+ public void testExplicitConfig() {
+ app1 = new Application("app1");
+ app2 = new Application("app2");
+ env1 = new Environment("env1");
+ env2 = new Environment("env2");
+
+ EdgeFilter restriction = new ConnectRequiredProvidedEdgeFilter("app2",
+ "string", "env1", "datasource");
+ compare(new Boolean[] { false, false, false, true }, restriction);
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+
import java.util.Properties;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ConfiguredProperties extends Properties {
-
- public ConfiguredProperties(String aProps) throws IOException {
- InputStream is = new ByteArrayInputStream(aProps.getBytes());
- load(is);
+ /**
+ * Creates a new ConfiguredProperties object.
+ *
+ *
+ */
+ public ConfiguredProperties(String aProps) throws IOException {
+ InputStream is = new ByteArrayInputStream(aProps.getBytes());
+ load(is);
is.close();
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
-import java.util.Properties;
-
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
+import java.util.Properties;
+
/**
- * Bean that provides postprocessing of the bean factory based on
- * a given set of properties.
+ * Bean that provides postprocessing of the bean factory based on a given set of
+ * properties.
*
* @author Erik Brakkee
*/
class PropertySetter extends PropertyPlaceholderConfigurer {
-
- /**
- * Constructs the property setter.
- * @param aProps Properties.
- */
- public PropertySetter(Properties aProps) {
- String propFile = createPropertyFile(aProps);
- setLocation(new StringResource(propFile));
- }
+ /**
+ * Constructs the property setter.
+ *
+ * @param aProps
+ * Properties.
+ */
+ public PropertySetter(Properties aProps) {
+ String propFile = createPropertyFile(aProps);
+ setLocation(new StringResource(propFile));
+ }
public static String createPropertyFile(Properties aProps) {
- StringBuffer buf = new StringBuffer();
- for (Object key: aProps.keySet()) {
- buf.append(key);
- buf.append("=");
- buf.append(aProps.get(key));
- buf.append("\n");
- }
+ StringBuffer buf = new StringBuffer();
+
+ for (Object key : aProps.keySet()) {
+ buf.append(key);
+ buf.append("=");
+ buf.append(aProps.get(key));
+ buf.append("\n");
+ }
+
return buf.toString();
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
-import java.util.List;
-
import org.springframework.beans.factory.FactoryBean;
+
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.SystemAssemblyException;
+import java.util.List;
+
/**
- * Bean which adds a service required by the spring component to
- * the application context so that other spring beans can use it.
- *
+ * Bean which adds a service required by the spring component to the application
+ * context so that other spring beans can use it.
+ *
* @author Erik Brakkee
*/
class RequiredServiceBean implements FactoryBean {
-
- private RequiredInterface _required;
-
- /**
- * Constructs the bean.
- * @param aId Id of the bean in the service registry.
- */
- public RequiredServiceBean(String aId) {
- List<RequiredInterface> required = SpringComponent.THIS.get().getRequiredInterfaces();
- for ( RequiredInterface intf: required) {
- if ( intf.getName().equals(aId)) {
- _required = intf;
- return;
- }
- }
- throw new SystemAssemblyException("Cannot resolve required component '" + aId + "'");
- }
+ private RequiredInterface required;
+
+ /**
+ * Constructs the bean.
+ *
+ * @param aId
+ * Id of the bean in the service registry.
+ */
+ public RequiredServiceBean(String aId) {
+ List<RequiredInterface> requiredInterfaces = SpringComponent.THIS.get()
+ .getRequiredInterfaces();
+
+ for (RequiredInterface intf : requiredInterfaces) {
+ if (intf.getName().equals(aId)) {
+ required = intf;
+
+ return;
+ }
+ }
- @Override
- public Object getObject() throws Exception {
- return SpringComponent.SCOPE.get().getInterfaceImplementation(
- _required.getProvider(), Object.class);
- }
+ throw new SystemAssemblyException(
+ "Cannot resolve required component '" + aId + "'");
+ }
- @Override
- public Class getObjectType() {
- return null;
- }
+ @Override
+ public Object getObject() throws Exception {
+ return SpringComponent.SCOPE.get().getInterfaceImplementation(
+ required.getProvider(), Object.class);
+ }
- @Override
- public boolean isSingleton() {
- return true;
- }
+ @Override
+ public Class getObjectType() {
+ return null;
+ }
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.RootBeanDefinition;
+
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
+
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.DefaultScope;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.Scope;
import org.wamblee.system.core.SystemAssemblyException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
/**
* Represents a system configured based on spring. The spring config files that
* are configured should not contain any PropertyPlaceholderConfigurer objects.
* @author Erik Brakkee
*/
public class SpringComponent extends AbstractComponent<Scope> {
+ private static final String CONTEXT_KEY = "context";
+
+ static final ThreadLocal<SpringComponent> THIS = new ThreadLocal<SpringComponent>();
+
+ static final ThreadLocal<Scope> SCOPE = new ThreadLocal<Scope>();
+
+ private Properties properties;
+
+ private String[] configFiles;
+
+ private Map<String, ProvidedInterface> provided;
+
+ private Map<RequiredInterface, String> required;
+
+ private Map<String, Properties> propertyObjects;
+
+ /**
+ * Constructs a spring system.
+ *
+ * @param aName
+ * Name of the system.
+ * @param aConfigFil
+ * Spring config files to read.
+ * @param aProvided
+ * Map of bean name to service descriptor describing the bean
+ * names that the spring config files use for each required
+ * service.
+ * @param aRequired
+ * Map of bean name to service descriptor describing the bean
+ * names that the spring config files use for each required
+ * service.
+ */
+ public SpringComponent(String aName, String[] aConfigFiles,
+ Map<String, ProvidedInterface> aProvided,
+ Map<RequiredInterface, String> aRequired) {
+ super(aName, aProvided.values().toArray(new ProvidedInterface[0]),
+ aRequired.keySet().toArray(new RequiredInterface[0]));
+ properties = new Properties();
+ configFiles = aConfigFiles;
+ provided = aProvided;
+ required = aRequired;
+ propertyObjects = new HashMap<String, Properties>();
+ }
+
+ /**
+ * Must be called to make a property available in the application context.
+ *
+ * @param aKey
+ * Property key.
+ * @param aValue
+ * Property value.
+ */
+ public void setProperty(String aKey, String aValue) {
+ properties.put(aKey, aValue);
+ }
+
+ public void addProperties(Properties aProperties) {
+ for (Object key : aProperties.keySet()) {
+ setProperty((String) key, aProperties.getProperty((String) key));
+ }
+ }
+
+ public void addProperties(String aBeanname, Properties aProperties) {
+ propertyObjects.put(aBeanname, aProperties);
+ }
+
+ public Properties getProperties(String aBeanname) {
+ return propertyObjects.get(aBeanname);
+ }
+
+ @Override
+ protected Scope doStart(Scope aExternalScope) {
+ SpringComponent old = THIS.get();
+ Scope oldScope = SCOPE.get();
+ THIS.set(this);
+
+ Scope scope = new DefaultScope(getProvidedInterfaces().toArray(
+ new ProvidedInterface[0]), aExternalScope);
+ SCOPE.set(scope);
+
+ try {
+ GenericApplicationContext parentContext = new GenericApplicationContext();
+
+ registerRequiredServices(parentContext);
+ registerPropertyObjects(parentContext);
+
+ parentContext.refresh();
- private static final String CONTEXT_KEY = "context";
-
- static final ThreadLocal<SpringComponent> THIS = new ThreadLocal<SpringComponent>();
- static final ThreadLocal<Scope> SCOPE = new ThreadLocal<Scope>();
-
- private Properties _properties;
- private String[] _configFiles;
- private Map<String, ProvidedInterface> _provided;
- private Map<RequiredInterface, String> _required;
- private Map<String, Properties> _propertyObjects;
-
- /**
- * Constructs a spring system.
- *
- * @param aName
- * Name of the system.
- * @param aConfigFil
- * Spring config files to read.
- * @param aProvided
- * Map of bean name to service descriptor describing the bean
- * names that the spring config files use for each required
- * service.
- * @param aRequired
- * Map of bean name to service descriptor describing the bean
- * names that the spring config files use for each required
- * service.
- */
- public SpringComponent(String aName, String[] aConfigFiles,
- Map<String, ProvidedInterface> aProvided,
- Map<RequiredInterface, String> aRequired) {
- super(aName, aProvided.values().toArray(new ProvidedInterface[0]),
- aRequired.keySet().toArray(new RequiredInterface[0]));
- _properties = new Properties();
- _configFiles = aConfigFiles;
- _provided = aProvided;
- _required = aRequired;
- _propertyObjects = new HashMap<String, Properties>();
-
- }
-
- /**
- * Must be called to make a property available in the application context.
- *
- * @param aKey
- * Property key.
- * @param aValue
- * Property value.
- */
- public void setProperty(String aKey, String aValue) {
- _properties.put(aKey, aValue);
- }
-
- public void addProperties(Properties aProperties) {
- for (Object key : aProperties.keySet()) {
- setProperty((String) key, aProperties.getProperty((String) key));
- }
- }
-
- public void addProperties(String aBeanname, Properties aProperties) {
- _propertyObjects.put(aBeanname, aProperties);
- }
-
- public Properties getProperties(String aBeanname) {
- return _propertyObjects.get(aBeanname);
- }
-
- @Override
- protected Scope doStart(Scope aExternalScope) {
-
- SpringComponent old = THIS.get();
- Scope oldScope = SCOPE.get();
- THIS.set(this);
- Scope scope = new DefaultScope(getProvidedInterfaces().toArray(new ProvidedInterface[0]), aExternalScope);
- SCOPE.set(scope);
- try {
- GenericApplicationContext parentContext = new GenericApplicationContext();
-
- registerRequiredServices(parentContext);
- registerPropertyObjects(parentContext);
-
- parentContext.refresh();
-
- System.out.println("Parent context " + parentContext);
-
- AbstractApplicationContext context = parseConfigFiles(parentContext);
-
- context
- .addBeanFactoryPostProcessor(new PropertySetter(_properties));
- context.refresh();
-
- exposeProvidedServices(context, aExternalScope);
-
- scope.put(CONTEXT_KEY, context);
- return scope;
- } catch (Exception e) {
- throw new SystemAssemblyException(
- "Failed to assemble spring system " + getName(), e);
- } finally {
- THIS.set(old);
- SCOPE.set(oldScope);
- }
- }
-
- private void exposeProvidedServices(AbstractApplicationContext aContext, Scope aScope) {
- // Call addService for each provided service.
-
- for (String name : _provided.keySet()) {
- Object svc = aContext.getBean(name);
- if (svc == null) {
- throw new IllegalArgumentException(getQualifiedName() + ": service '"
- + name + "' is null");
- }
- addInterface(_provided.get(name), svc, aScope);
- System.out.println("addService " + _provided.get(name) + " " + svc);
- }
- }
-
- private AbstractApplicationContext parseConfigFiles(GenericApplicationContext aParentContext) {
- // Parse spring config files
-
- return new ClassPathXmlApplicationContext((String[]) _configFiles,
- false, aParentContext);
- }
-
- private void registerRequiredServices(GenericApplicationContext aParentContext) {
- // Register required services in a parent context
- for (RequiredInterface required: getRequiredInterfaces()) {
- String beanName = _required.get(required);
- if ( beanName != null && beanName.length() > 0) {
- ConstructorArgumentValues cargs = new ConstructorArgumentValues();
- cargs.addGenericArgumentValue(required.getName());
- BeanDefinition definition = new RootBeanDefinition(
- RequiredServiceBean.class, cargs,
- new MutablePropertyValues());
- aParentContext.registerBeanDefinition(beanName, definition);
- } else {
- // The required interface is not required by the spring config but by the sub-class directly.
- }
- }
- }
-
- private void registerPropertyObjects(GenericApplicationContext aParentContext) {
- for (String beanName: _propertyObjects.keySet()) {
+ System.out.println("Parent context " + parentContext);
+
+ AbstractApplicationContext context = parseConfigFiles(parentContext);
+
+ context.addBeanFactoryPostProcessor(new PropertySetter(properties));
+ context.refresh();
+
+ exposeProvidedServices(context, aExternalScope);
+
+ scope.put(CONTEXT_KEY, context);
+
+ return scope;
+ } catch (Exception e) {
+ throw new SystemAssemblyException(
+ "Failed to assemble spring system " + getName(), e);
+ } finally {
+ THIS.set(old);
+ SCOPE.set(oldScope);
+ }
+ }
+
+ private void exposeProvidedServices(AbstractApplicationContext aContext,
+ Scope aScope) {
+ // Call addService for each provided service.
+ for (String name : provided.keySet()) {
+ Object svc = aContext.getBean(name);
+
+ if (svc == null) {
+ throw new IllegalArgumentException(getQualifiedName() +
+ ": service '" + name + "' is null");
+ }
+
+ addInterface(provided.get(name), svc, aScope);
+ System.out.println("addService " + provided.get(name) + " " + svc);
+ }
+ }
+
+ private AbstractApplicationContext parseConfigFiles(
+ GenericApplicationContext aParentContext) {
+ // Parse spring config files
+ return new ClassPathXmlApplicationContext((String[]) configFiles,
+ false, aParentContext);
+ }
+
+ private void registerRequiredServices(
+ GenericApplicationContext aParentContext) {
+ // Register required services in a parent context
+ for (RequiredInterface requiredIntf : getRequiredInterfaces()) {
+ String beanName = required.get(requiredIntf);
+
+ if ((beanName != null) && (beanName.length() > 0)) {
+ ConstructorArgumentValues cargs = new ConstructorArgumentValues();
+ cargs.addGenericArgumentValue(requiredIntf.getName());
+
+ BeanDefinition definition = new RootBeanDefinition(
+ RequiredServiceBean.class, cargs,
+ new MutablePropertyValues());
+ aParentContext.registerBeanDefinition(beanName, definition);
+ } else {
+ // The required interface is not required by the spring config
+ // but by the sub-class directly.
+ }
+ }
+ }
+
+ private void registerPropertyObjects(
+ GenericApplicationContext aParentContext) {
+ for (String beanName : propertyObjects.keySet()) {
ConstructorArgumentValues cargs = new ConstructorArgumentValues();
- cargs.addGenericArgumentValue(PropertySetter.createPropertyFile(_propertyObjects.get(beanName)));
+ cargs.addGenericArgumentValue(PropertySetter
+ .createPropertyFile(propertyObjects.get(beanName)));
+
BeanDefinition definition = new RootBeanDefinition(
- ConfiguredProperties.class, cargs,
- new MutablePropertyValues());
+ ConfiguredProperties.class, cargs, new MutablePropertyValues());
aParentContext.registerBeanDefinition(beanName, definition);
}
}
-
- @Override
- protected void doStop(Scope aRuntime) {
- AbstractApplicationContext context = (AbstractApplicationContext)aRuntime.get(CONTEXT_KEY);
- context.close();
- }
+ @Override
+ protected void doStop(Scope aRuntime) {
+ AbstractApplicationContext context = (AbstractApplicationContext) aRuntime
+ .get(CONTEXT_KEY);
+ context.close();
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
+import org.springframework.core.io.Resource;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URL;
-import org.springframework.core.io.Resource;
+import java.net.URL;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
class StringResource implements Resource {
-
- private String _value;
-
- public StringResource(String aValue) {
- _value = aValue;
- }
+ private String value;
- @Override
- public Resource createRelative(String aRelativePath) throws IOException {
- throw new IOException("No relative resource possible");
- }
+ /**
+ * Creates a new StringResource object.
+ *
+ */
+ public StringResource(String aValue) {
+ value = aValue;
+ }
- @Override
- public boolean exists() {
- return false;
- }
+ @Override
+ public Resource createRelative(String aRelativePath) throws IOException {
+ throw new IOException("No relative resource possible");
+ }
- @Override
- public String getDescription() {
- return "Properties of a spring component";
- }
+ @Override
+ public boolean exists() {
+ return false;
+ }
- @Override
- public File getFile() throws IOException {
- throw new IOException();
- }
+ @Override
+ public String getDescription() {
+ return "Properties of a spring component";
+ }
- @Override
- public String getFilename() {
- return "springcomponent.properties";
- }
+ @Override
+ public File getFile() throws IOException {
+ throw new IOException();
+ }
- @Override
- public URL getURL() throws IOException {
- throw new IOException();
- }
+ @Override
+ public String getFilename() {
+ return "springcomponent.properties";
+ }
- @Override
- public boolean isOpen() {
- return false;
- }
+ @Override
+ public URL getURL() throws IOException {
+ throw new IOException();
+ }
- @Override
- public InputStream getInputStream() throws IOException {
- return new ByteArrayInputStream(_value.getBytes());
- }
+ @Override
+ public boolean isOpen() {
+ return false;
+ }
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(value.getBytes());
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.spring.component;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TreeMap;
-
-import javax.sql.DataSource;
-
import org.springframework.core.io.ClassPathResource;
+
import org.springframework.jdbc.datasource.DriverManagerDataSource;
+
import org.wamblee.system.components.ORMappingConfig;
import org.wamblee.system.components.ORMappingConfig.DatabaseType;
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.Scope;
import org.wamblee.system.spring.SpringComponent;
+import java.io.IOException;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+import javax.sql.DataSource;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DatasourceComponent extends AbstractComponent<DataSource> {
+ private static RequiredInterface PROPS = new DefaultRequiredInterface(
+ "dbprops", Properties.class);
+
+ private static ProvidedInterface DATASOURCE = new DefaultProvidedInterface(
+ "datasource", DataSource.class);
- private static RequiredInterface PROPS = new DefaultRequiredInterface("dbprops", Properties.class);
- private static ProvidedInterface DATASOURCE = new DefaultProvidedInterface("datasource",
- DataSource.class);
- private static ProvidedInterface ORM_CONFIG = new DefaultProvidedInterface("ormconfig",
- ORMappingConfig.class);
-
+ private static ProvidedInterface ORM_CONFIG = new DefaultProvidedInterface(
+ "ormconfig", ORMappingConfig.class);
+
+ /**
+ * Creates a new DatasourceComponent object.
+ *
+ *
+ */
public DatasourceComponent(String aName) throws IOException {
- super(aName);
-
+ super(aName);
+
addRequiredInterface(PROPS);
addProvidedInterface(DATASOURCE);
addProvidedInterface(ORM_CONFIG);
}
-
@Override
protected DataSource doStart(Scope aScope) {
- Properties dbProps = aScope.getInterfaceImplementation(
- PROPS.getProvider(), Properties.class);
- DriverManagerDataSource ds = new DriverManagerDataSource(
- dbProps.getProperty("database.url"),
- dbProps.getProperty("database.username"),
- dbProps.getProperty("database.password"));
- addInterface(DATASOURCE, ds, aScope);
- DatabaseType type = DatabaseType.valueOf(dbProps.getProperty("database.type"));
-
- ORMappingConfig config = new ORMappingConfig(true, type);
-
- addInterface(ORM_CONFIG, config, aScope);
-
- return ds;
+ Properties dbProps = aScope.getInterfaceImplementation(PROPS
+ .getProvider(), Properties.class);
+ DriverManagerDataSource ds = new DriverManagerDataSource(dbProps
+ .getProperty("database.url"), dbProps
+ .getProperty("database.username"), dbProps
+ .getProperty("database.password"));
+ addInterface(DATASOURCE, ds, aScope);
+
+ DatabaseType type = DatabaseType.valueOf(dbProps
+ .getProperty("database.type"));
+
+ ORMappingConfig config = new ORMappingConfig(true, type);
+
+ addInterface(ORM_CONFIG, config, aScope);
+
+ return ds;
}
@Override
protected void doStop(DataSource aRuntime) {
- // Empty.
+ // Empty.
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring.component;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-
import org.hibernate.SessionFactory;
+
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.MySQLInnoDBDialect;
+
import org.springframework.orm.hibernate3.HibernateTemplate;
+
import org.springframework.transaction.PlatformTransactionManager;
+
import org.wamblee.persistence.hibernate.HibernateMappingFiles;
+
import org.wamblee.system.components.ORMappingConfig;
import org.wamblee.system.components.ORMappingConfig.DatabaseType;
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.Scope;
import org.wamblee.system.spring.SpringComponent;
-public class HibernateComponent extends SpringComponent {
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class HibernateComponent extends SpringComponent {
private static final String HIBERNATE_DIALECT_PROP = "hibernate.dialect";
+
private static final String HIBERNATE_SCHEMAUPDATE_PROP = "hibernate.schemaupdate";
+
private static final String HIBERNATE_PROPS_KEY = "hibernateProperties";
+
private static final String HIBERNATE_SPRING_CONFIG = "spring/org.wamblee.system.spring.component.hibernate.xml";
-
- private final RequiredInterface CONFIG = new DefaultRequiredInterface("config", ORMappingConfig.class);
-
- public HibernateComponent(String aName) throws IOException {
- super(aName, new String[] { HIBERNATE_SPRING_CONFIG},
- createProvided(), createRequired());
-
- Properties props = new Properties();
+
+ private final RequiredInterface config = new DefaultRequiredInterface(
+ "config", ORMappingConfig.class);
+
+ /**
+ * Creates a new HibernateComponent object.
+ *
+ *
+ */
+ public HibernateComponent(String aName) throws IOException {
+ super(aName, new String[] { HIBERNATE_SPRING_CONFIG },
+ createProvided(), createRequired());
+
+ Properties props = new Properties();
addProperties(HIBERNATE_PROPS_KEY, props);
-
- addRequiredInterface(CONFIG);
+
+ addRequiredInterface(config);
}
-
+
@Override
protected Scope doStart(Scope aExternalScope) {
-
- ORMappingConfig config = aExternalScope.getInterfaceImplementation(CONFIG.getProvider(), ORMappingConfig.class);
- setProperty(HIBERNATE_SCHEMAUPDATE_PROP, "" + config.isSchemaUpdate());
-
- DatabaseType db = config.getType();
- String dialect = db.handleCases(new DatabaseType.Switch<String>() {
+ ORMappingConfig orMappingConfig = aExternalScope.getInterfaceImplementation(
+ config.getProvider(), ORMappingConfig.class);
+ setProperty(HIBERNATE_SCHEMAUPDATE_PROP, "" + orMappingConfig.isSchemaUpdate());
+
+ DatabaseType db = orMappingConfig.getType();
+ String dialect = db.handleCases(new DatabaseType.Switch<String>() {
@Override
public String handleMySqlInnoDb() {
- return MySQLInnoDBDialect.class.getName();
+ return MySQLInnoDBDialect.class.getName();
}
+
@Override
public String handleDerby() {
- return DerbyDialect.class.getName();
+ return DerbyDialect.class.getName();
}
});
+
getHibernateProperties().put(HIBERNATE_DIALECT_PROP, dialect);
-
-
+
return super.doStart(aExternalScope);
}
-
- private Properties getHibernateProperties() {
+
+ private Properties getHibernateProperties() {
return getProperties(HIBERNATE_PROPS_KEY);
}
private static Map<RequiredInterface, String> createRequired() {
- Map<RequiredInterface,String> required = new HashMap<RequiredInterface, String>();
- required.put(new DefaultRequiredInterface("datasource", DataSource.class), "dataSource");
- required.put(new DefaultRequiredInterface("mappingFiles", HibernateMappingFiles.class),
- "hibernateMappingFiles");
+ Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
+ required.put(new DefaultRequiredInterface("datasource",
+ DataSource.class), "dataSource");
+ required.put(new DefaultRequiredInterface("mappingFiles",
+ HibernateMappingFiles.class), "hibernateMappingFiles");
+
return required;
}
private static Map<String, ProvidedInterface> createProvided() {
- Map<String,ProvidedInterface> provided = new HashMap<String,ProvidedInterface>();
-
+ Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
+
provided.put("transactionManager", new DefaultProvidedInterface(
- "transactionMgr", PlatformTransactionManager.class));
+ "transactionMgr", PlatformTransactionManager.class));
provided.put("sessionFactory", new DefaultProvidedInterface(
- "sessionFactory", SessionFactory.class));
- provided.put("org.springframework.orm.hibernate3.HibernateTemplate", new DefaultProvidedInterface(
- "hibernateTemplate", HibernateTemplate.class));
+ "sessionFactory", SessionFactory.class));
+ provided.put("org.springframework.orm.hibernate3.HibernateTemplate",
+ new DefaultProvidedInterface("hibernateTemplate",
+ HibernateTemplate.class));
+
return provided;
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class BlaService {
- private HelloService _hello;
-
- public BlaService(HelloService aService) {
- if ( aService == null ) {
- throw new IllegalArgumentException("helloService is null");
- }
- _hello = aService;
- }
-
- public String execute() {
- return _hello.say();
- }
-
- public void stop() {
- System.out.println("Blaservice stopping");
- }
+ private HelloService hello;
+
+ /**
+ * Creates a new BlaService object.
+ *
+ */
+ public BlaService(HelloService aService) {
+ if (aService == null) {
+ throw new IllegalArgumentException("helloService is null");
+ }
+
+ hello = aService;
+ }
+
+ public String execute() {
+ return hello.say();
+ }
+
+ public void stop() {
+ System.out.println("Blaservice stopping");
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
+import junit.framework.TestCase;
+
import java.io.IOException;
-import java.util.Properties;
-import junit.framework.TestCase;
+import java.util.Properties;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class ConfiguredPropertiesTest extends TestCase {
-
- public void testProps() throws IOException {
+ public void testProps() throws IOException {
Properties props = new Properties();
props.put("x", "y");
- props.put("a", "b");
-
- ConfiguredProperties props2 = new ConfiguredProperties(
- PropertySetter.createPropertyFile(props));
-
- assertEquals(props.size(), props2.size());
+ props.put("a", "b");
+
+ ConfiguredProperties props2 = new ConfiguredProperties(PropertySetter
+ .createPropertyFile(props));
+
+ assertEquals(props.size(), props2.size());
assertEquals(props.get("x"), props2.get("x"));
assertEquals(props.get("a"), props2.get("a"));
}
}
-
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class HelloService {
-
- private String _msg;
-
- public HelloService(String aMsg) {
- SpringComponentTest.EVENT_TRACKER.eventOccurred(aMsg);
- _msg = aMsg;
- }
-
- public String say() {
- return _msg;
- }
+ private String msg;
+
+ /**
+ * Creates a new HelloService object.
+ *
+ */
+ public HelloService(String aMsg) {
+ SpringComponentTest.getEventTracker().eventOccurred(aMsg);
+ msg = aMsg;
+ }
+
+ public String say() {
+ return msg;
+ }
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.spring;
import java.util.Properties;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class HelloService2 {
+ private Properties props;
- private Properties _props;
-
+ /**
+ * Creates a new HelloService2 object.
+ *
+ */
public HelloService2(Properties aProps) {
- _props = aProps;
+ props = aProps;
}
- public Properties getProperties() {
- return _props;
+ public Properties getProperties() {
+ return props;
}
}
/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.spring;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
import junit.framework.TestCase;
import org.wamblee.io.ClassPathResource;
+
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.DefaultRequiredInterface;
import org.wamblee.system.core.DefaultScope;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
import org.wamblee.system.core.SystemAssemblyException;
+
import org.wamblee.test.EventTracker;
-public class SpringComponentTest extends TestCase {
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class SpringComponentTest extends TestCase {
private static final String HELLO_SERVICE_SPRING_XML = "test.org.wamblee.system.spring.xml";
+
private static final String HELLO_SERVICE_SPRING_WITH_REQS_XML = "test.org.wamblee.system.springWithRequirements.xml";
+
private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
+
private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 = "test.org.wamblee.system.springWithProperties2.xml";
private static final String PROPERTY_FILE = "test.org.wamblee.system.spring.properties";
- public static EventTracker<String> EVENT_TRACKER;
+ private static EventTracker<String> EVENT_TRACKER;
- private Scope _externalScope;
+ private Scope externalScope;
+ public static EventTracker<String> getEventTracker() {
+ return EVENT_TRACKER;
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
EVENT_TRACKER = new EventTracker<String>();
- _externalScope = new DefaultScope(new ProvidedInterface[0]);
+ externalScope = new DefaultScope(new ProvidedInterface[0]);
}
public void testBlackboxSystem() {
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_XML },
- new HashMap<String, ProvidedInterface>(),
- new HashMap<RequiredInterface, String>());
+ new String[] { HELLO_SERVICE_SPRING_XML },
+ new HashMap<String, ProvidedInterface>(),
+ new HashMap<RequiredInterface, String>());
- Scope runtime = system.start(_externalScope);
- assertEquals(0, _externalScope.getProvidedInterfaces().size());
+ Scope runtime = system.start(externalScope);
+ assertEquals(0, externalScope.getProvidedInterfaces().size());
system.stop(runtime);
}
public void testOneProvidedService() {
Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
provided.put("helloService", new DefaultProvidedInterface("hello",
- HelloService.class));
+ HelloService.class));
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_XML }, provided,
- new HashMap<RequiredInterface, String>());
- Scope runtime = system.start(_externalScope);
+ new String[] { HELLO_SERVICE_SPRING_XML }, provided,
+ new HashMap<RequiredInterface, String>());
+ Scope runtime = system.start(externalScope);
List<ProvidedInterface> services = runtime.getProvidedInterfaces();
assertEquals(1, services.size());
+
Object service = runtime.getInterfaceImplementation(services.get(0),
- Object.class);
+ Object.class);
assertTrue(service instanceof HelloService);
// BUG; Provided services should be made available in the external
// scope.
- Object service2 = _externalScope.getInterfaceImplementation(provided
- .get("helloService"), Object.class);
+ Object service2 = externalScope.getInterfaceImplementation(provided
+ .get("helloService"), Object.class);
assertSame(service, service2);
assertEquals("Hello world!", ((HelloService) service).say());
public void testWithProperties() throws IOException {
Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
provided.put("helloService", new DefaultProvidedInterface("hello",
- HelloService.class));
+ HelloService.class));
+
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
- provided, new HashMap<RequiredInterface, String>());
+ new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
+ provided, new HashMap<RequiredInterface, String>());
Properties props = new Properties();
props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
system.addProperties(props);
- Scope scope = system.start(_externalScope);
+ Scope scope = system.start(externalScope);
// BUG: Hello service was constructed multiple times. Once with the
// unprocessed property
// and another time with the processed property.
assertEquals(1, EVENT_TRACKER.getEventCount());
+
List<ProvidedInterface> services = scope.getProvidedInterfaces();
assertEquals("Property Value", scope.getInterfaceImplementation(
- services.get(0), HelloService.class).say());
+ services.get(0), HelloService.class).say());
}
public void testWithPropertiesAsBean() throws IOException {
Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
provided.put("helloService", new DefaultProvidedInterface("hello",
- HelloService2.class));
+ HelloService2.class));
+
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 },
- provided, new HashMap<RequiredInterface, String>());
+ new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 },
+ provided, new HashMap<RequiredInterface, String>());
Properties props = new Properties();
props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
system.addProperties("properties", props);
- Scope scope = system.start(_externalScope);
+ Scope scope = system.start(externalScope);
List<ProvidedInterface> services = scope.getProvidedInterfaces();
Properties props2 = scope.getInterfaceImplementation(services.get(0),
- HelloService2.class).getProperties();
+ HelloService2.class).getProperties();
assertEquals(props, props2);
}
public void testWithMissingRequirement() {
try {
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
- new HashMap<String, ProvidedInterface>(),
- new HashMap<RequiredInterface, String>());
- system.start(_externalScope);
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
+ new HashMap<String, ProvidedInterface>(),
+ new HashMap<RequiredInterface, String>());
+ system.start(externalScope);
} catch (SystemAssemblyException e) {
// e.printStackTrace();
return;
}
+
fail();
}
public void testWithRequirement() {
Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
required.put(new DefaultRequiredInterface("hello", HelloService.class),
- "helloService");
+ "helloService");
+
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
- new HashMap<String, ProvidedInterface>(), required);
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
+ new HashMap<String, ProvidedInterface>(), required);
HelloService helloObject = new HelloService("ladida");
ProvidedInterface helloService = new DefaultProvidedInterface("hello",
- HelloService.class);
+ HelloService.class);
Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
scope.publishInterface(helloService, helloObject);
system.getRequiredInterfaces().get(0).setProvider(helloService);
public void testWithRequirementAndProvidedService() {
Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
required.put(new DefaultRequiredInterface("hello", HelloService.class),
- "helloService");
+ "helloService");
+
Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
provided.put("blaService", new DefaultProvidedInterface("bla",
- BlaService.class));
+ BlaService.class));
SpringComponent system = new SpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML }, provided,
- required);
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML }, provided,
+ required);
HelloService helloObject = new HelloService("ladida");
ProvidedInterface helloService = new DefaultProvidedInterface("hello",
- HelloService.class);
+ HelloService.class);
Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
scope.publishInterface(helloService, helloObject);
system.getRequiredInterfaces().get(0).setProvider(helloService);
+
Scope runtime = system.start(scope);
ProvidedInterface started = runtime.getProvidedInterfaces().get(0);
Object impl = runtime.getInterfaceImplementation(started,
- BlaService.class);
+ BlaService.class);
assertNotNull(impl);
assertTrue(impl instanceof BlaService);
assertEquals("ladida", ((BlaService) impl).execute());
public void testWithProvidedFromSubClassNotFromConfig() {
Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
provided.put("helloService", new DefaultProvidedInterface("hello",
- HelloService.class));
+ HelloService.class));
SubSpringComponent system = new SubSpringComponent("system",
- new String[] { HELLO_SERVICE_SPRING_XML }, provided,
- new HashMap<RequiredInterface, String>());
+ new String[] { HELLO_SERVICE_SPRING_XML }, provided,
+ new HashMap<RequiredInterface, String>());
- Scope runtime = system.start(_externalScope);
+ Scope runtime = system.start(externalScope);
List<ProvidedInterface> services = runtime.getProvidedInterfaces();
assertEquals(2, services.size());
+
Object service = runtime.getInterfaceImplementation(services.get(0),
- Object.class);
+ Object.class);
assertTrue(service instanceof HelloService);
// BUG; Provided services should be made available in the external
// scope.
- Object service2 = _externalScope.getInterfaceImplementation(provided
- .get("helloService"), Object.class);
+ Object service2 = externalScope.getInterfaceImplementation(provided
+ .get("helloService"), Object.class);
assertSame(service, service2);
- Object floatsvc = _externalScope.getInterfaceImplementation(system
- .getProvidedInterfaces().get(1), Object.class);
+ Object floatsvc = externalScope.getInterfaceImplementation(system
+ .getProvidedInterfaces().get(1), Object.class);
assertTrue(floatsvc instanceof Float);
assertTrue((((Float) floatsvc).floatValue() - 100.345f) < 0.00001);
}
/**
- * Tests the spring component with an additional requirement from the subclass
- * which is not required by the spring config files inside.
+ * Tests the spring component with an additional requirement from the
+ * subclass which is not required by the spring config files inside.
*/
public void testWithRequirementFromSubClass() {
Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
required.put(new DefaultRequiredInterface("hello", HelloService.class),
- "helloService");
+ "helloService");
+
SpringComponent system = new SubSpringComponent2("system",
- new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
- new HashMap<String, ProvidedInterface>(), required);
+ new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
+ new HashMap<String, ProvidedInterface>(), required);
HelloService helloObject = new HelloService("ladida");
ProvidedInterface helloService = new DefaultProvidedInterface("hello",
- HelloService.class);
-
- ProvidedInterface floatService = new DefaultProvidedInterface("float", Float.class);
-
+ HelloService.class);
+
+ ProvidedInterface floatService = new DefaultProvidedInterface("float",
+ Float.class);
+
Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
scope.publishInterface(helloService, helloObject);
scope.publishInterface(floatService, 100.234f);
Scope runtime = system.start(scope);
system.stop(runtime);
-
- assertEquals(100.234f, ((Float)runtime.get("floatValue")).floatValue(), 0.0001f);
- }
+ assertEquals(100.234f,
+ ((Float) runtime.get("floatValue")).floatValue(), 0.0001f);
+ }
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
-import java.util.Map;
-
-
import org.wamblee.system.core.DefaultProvidedInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+import java.util.Map;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class SubSpringComponent extends SpringComponent {
-
- private static ProvidedInterface PROVIDED = new DefaultProvidedInterface("provided", Float.class);
+ private static ProvidedInterface PROVIDED = new DefaultProvidedInterface(
+ "provided", Float.class);
+ /**
+ * Creates a new SubSpringComponent object.
+ *
+ */
public SubSpringComponent(String aName, String[] aConfigFiles,
- Map<String, ProvidedInterface> aProvided,
- Map<RequiredInterface, String> aRequired) {
+ Map<String, ProvidedInterface> aProvided,
+ Map<RequiredInterface, String> aRequired) {
super(aName, aConfigFiles, aProvided, aRequired);
addProvidedInterface(PROVIDED);
}
-
+
@Override
protected Scope doStart(Scope aExternalScope) {
-
Scope scope = super.doStart(aExternalScope);
addInterface(PROVIDED, 100.345f, aExternalScope);
+
return scope;
}
}
/*
- * Copyright 2008 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.spring;
-import java.util.Map;
-
import org.wamblee.system.core.DefaultRequiredInterface;
import org.wamblee.system.core.ProvidedInterface;
import org.wamblee.system.core.RequiredInterface;
import org.wamblee.system.core.Scope;
+import java.util.Map;
+
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class SubSpringComponent2 extends SpringComponent {
-
- private static RequiredInterface REQUIRED = new DefaultRequiredInterface("required", Float.class);
+ private static RequiredInterface REQUIRED = new DefaultRequiredInterface(
+ "required", Float.class);
+ /**
+ * Creates a new SubSpringComponent2 object.
+ *
+ */
public SubSpringComponent2(String aName, String[] aConfigFiles,
- Map<String, ProvidedInterface> aProvided,
- Map<RequiredInterface, String> aRequired) {
+ Map<String, ProvidedInterface> aProvided,
+ Map<RequiredInterface, String> aRequired) {
super(aName, aConfigFiles, aProvided, aRequired);
addRequiredInterface(REQUIRED);
}
-
+
@Override
protected Scope doStart(Scope aExternalScope) {
-
Scope scope = super.doStart(aExternalScope);
-
- float value = aExternalScope.getInterfaceImplementation(REQUIRED.getProvider(), Float.class);
+
+ float value = aExternalScope.getInterfaceImplementation(REQUIRED
+ .getProvider(), Float.class);
scope.put("floatValue", value);
+
return scope;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.system.spring.component;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.sql.DataSource;
-
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.dbunit.DatabaseUnitException;
+
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.DatabaseSequenceFilter;
import org.dbunit.database.IDatabaseConnection;
+
import org.dbunit.dataset.FilteredDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.filter.ITableFilter;
+
import org.dbunit.operation.DatabaseOperation;
+
import org.hibernate.SessionFactory;
+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+
import org.springframework.context.ApplicationContext;
+
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
+
import org.springframework.orm.hibernate3.HibernateTemplate;
+
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
+
import org.wamblee.test.spring.TestTransactionCallback;
import org.wamblee.test.spring.TestTransactionCallbackWithoutResult;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.sql.DataSource;
+
/**
* Test support class for database testing. Currently, this still requires the
* spring platform transaction manager and hibernate template.
*/
public class DatabaseTesterComponent {
-
private static final Log LOG = LogFactory
- .getLog(DatabaseTesterComponent.class);
+ .getLog(DatabaseTesterComponent.class);
/**
* Schema pattern.
/**
* Cached spring application context.
*/
- private ApplicationContext _context;
+ private ApplicationContext context;
- private HibernateTemplate _hibernateTemplate;
+ private HibernateTemplate hibernateTemplate;
- private PlatformTransactionManager _transactionManager;
+ private PlatformTransactionManager transactionManager;
- private DataSource _dataSource;
+ private DataSource dataSource;
+ /**
+ * Creates a new DatabaseTesterComponent object.
+ *
+ */
public DatabaseTesterComponent(HibernateTemplate aHibernateTemplate,
- PlatformTransactionManager aTransactionManager,
- DataSource aDataSource) {
- _hibernateTemplate = aHibernateTemplate;
- _transactionManager = aTransactionManager;
- _dataSource = aDataSource;
+ PlatformTransactionManager aTransactionManager, DataSource aDataSource) {
+ hibernateTemplate = aHibernateTemplate;
+ transactionManager = aTransactionManager;
+ dataSource = aDataSource;
}
/**
+ *
* @return Hibernate session factory.
*/
protected SessionFactory getSessionFactory() {
- return _hibernateTemplate.getSessionFactory();
+ return hibernateTemplate.getSessionFactory();
}
/**
* Performs common initialization for test cases:
* <ul>
- * <li>Cleaning the database. </li>
+ * <li>Cleaning the database.</li>
* </ul>
*
* @throws Exception
}
/**
+ *
* @return Transaction manager
*/
protected PlatformTransactionManager getTransactionManager() {
- return _transactionManager;
+ return transactionManager;
}
/**
+ *
* @return Starts a new transaction.
*/
protected TransactionStatus getTransaction() {
* @return Hibernate template.
*/
public HibernateTemplate getTemplate() {
- return _hibernateTemplate;
+ return hibernateTemplate;
}
/**
* Flushes the session. Should be called after some Hibernate work and
* before JDBC is used to check results.
- *
*/
public void flush() {
getTemplate().flush();
* Flushes the session first and then removes all objects from the Session
* cache. Should be called after some Hibernate work and before JDBC is used
* to check results.
- *
*/
public void clear() {
flush();
}
public void cleanDatabase() throws SQLException {
-
if (!isDatabaseConfigured()) {
return;
}
try {
IDatabaseConnection connection = new DatabaseConnection(
- getConnection());
+ getConnection());
ITableFilter filter = new DatabaseSequenceFilter(connection, tables);
IDataSet dataset = new FilteredDataSet(filter, connection
- .createDataSet(tables));
+ .createDataSet(tables));
DatabaseOperation.DELETE_ALL.execute(connection, dataset);
} catch (DatabaseUnitException e) {
}
/**
+ *
+ *
* @throws SQLException
*/
public String[] getTableNames() throws SQLException {
-
List<String> result = new ArrayList<String>();
- LOG.debug("Getting database table names to clean (schema: '"
- + SCHEMA_PATTERN + "'");
+ LOG.debug("Getting database table names to clean (schema: '" +
+ SCHEMA_PATTERN + "'");
ResultSet tables = getConnection().getMetaData().getTables(null,
- SCHEMA_PATTERN, "%", new String[] { "TABLE" });
+ SCHEMA_PATTERN, "%", new String[] { "TABLE" });
+
while (tables.next()) {
String table = tables.getString("TABLE_NAME");
+
// Make sure we do not touch hibernate's specific
// infrastructure tables.
if (!table.toLowerCase().startsWith("hibernate")) {
result.add(table);
- LOG.debug("Adding " + table
- + " to list of tables to be cleaned.");
+ LOG.debug("Adding " + table +
+ " to list of tables to be cleaned.");
}
}
+
return (String[]) result.toArray(new String[0]);
}
/**
- * @return
+ *
+ *
* @throws SQLException
*/
public void emptyTables(List aTableList) throws SQLException {
Iterator liTable = aTableList.iterator();
+
while (liTable.hasNext()) {
emptyTable((String) liTable.next());
}
}
/**
- * @return
+ *
+ *
* @throws SQLException
*/
public void emptyTable(String aTable) throws SQLException {
}
/**
- * @return
+ *
+ *
* @throws SQLException
*/
public void dropTable(String aTable) throws SQLException {
*
* @param aSql
* SQL statement.
+ *
* @return Return code of the corresponding JDBC call.
*/
public int executeSql(final String aSql) {
* SQL statement.
* @param aArg
* Argument of the sql statement.
+ *
* @return Return code of the corresponding JDBC call.
*/
public int executeSql(final String aSql, final Object aArg) {
* SQL query to execute.
* @param aArgs
* Arguments.
+ *
* @return Number of rows updated.
*/
public int executeSql(final String aSql, final Object[] aArgs) {
*
* @param aCallback
* Callback to do your transactional work.
+ *
* @return Result.
*/
public Object executeTransaction(TransactionCallback aCallback) {
TransactionTemplate lTemplate = new TransactionTemplate(
- getTransactionManager());
+ getTransactionManager());
+
return lTemplate.execute(aCallback);
}
*/
public void executeTransaction(TransactionCallbackWithoutResult aCallback) {
TransactionTemplate template = new TransactionTemplate(
- getTransactionManager());
+ getTransactionManager());
template.execute(aCallback);
}
*
* @param aCallback
* Code to be executed within the transaction.
+ *
* @return Result.
+ *
*/
public Map executeTransaction(final TestTransactionCallback aCallback) {
return (Map) executeTransaction(new TransactionCallback() {
*
* @param aCallback
* Code to be executed within the transaction.
+ *
*/
public void executeTransaction(
- final TestTransactionCallbackWithoutResult aCallback) {
+ final TestTransactionCallbackWithoutResult aCallback) {
executeTransaction(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus aArg) {
try {
*
* @param aSql
* Query to execute.
+ *
* @return Result set.
*/
public ResultSet executeQuery(String aSql) {
* Query.
* @param aArg
* Argument.
+ *
* @return Result set.
*/
public ResultSet executeQuery(String aSql, Object aArg) {
* Sql query.
* @param aArgs
* Arguments to the query.
+ *
* @return Result set.
+ *
*/
public ResultSet executeQuery(final String aSql, final Object[] aArgs) {
try {
* Arguments to the prepared statement.
* @param aStatement
* Prepared statement
+ *
* @throws SQLException
*/
private void setPreparedParams(final Object[] aArgs,
- PreparedStatement aStatement) throws SQLException {
+ PreparedStatement aStatement) throws SQLException {
for (int i = 1; i <= aArgs.length; i++) {
setPreparedParam(i, aStatement, aArgs[i - 1]);
}
* @param aStatement
* Prepared statement.
* @param aObject
- * Value Must be of type Integer, Long, or String.
+ * Value Must be of type Integer, Long, or String.
+ *
* @throws SQLException
*/
private void setPreparedParam(int aIndex, PreparedStatement aStatement,
- Object aObject) throws SQLException {
+ Object aObject) throws SQLException {
if (aObject instanceof Integer) {
aStatement.setInt(aIndex, ((Integer) aObject).intValue());
} else if (aObject instanceof Long) {
} else if (aObject instanceof String) {
aStatement.setString(aIndex, (String) aObject);
} else {
- TestCase.fail("Unsupported object type for prepared statement: "
- + aObject.getClass() + " value: " + aObject
- + " statement: " + aStatement);
+ TestCase.fail("Unsupported object type for prepared statement: " +
+ aObject.getClass() + " value: " + aObject + " statement: " +
+ aStatement);
}
}
} catch (NoSuchBeanDefinitionException e) {
return false;
}
+
return true;
}
/**
+ *
* @return Returns the dataSource.
*/
public DataSource getDataSource() {
- return _dataSource;
+ return dataSource;
}
/**
+ *
+ *
* @return
+ *
* @throws SQLException
*/
public int getTableSize(final String aTable) throws SQLException {
-
ResultSet resultSet = executeQuery("select * from " + aTable);
int count = 0;
while (resultSet.next()) {
count++;
}
+
return count;
}
return count;
}
-
}
--- /dev/null
+
+Behavior which requires a persistence provider but does not use the persistence provider
+extensively is only tested with hibernate.
+
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.eclipselink;
-import java.util.Map;
-
import org.dbunit.dataset.filter.ITableFilterSimple;
+
import org.wamblee.support.persistence.JpaCustomizer;
import org.wamblee.support.persistence.PersistenceUnitDescription;
-public class EclipselinkJpaCustomizer implements JpaCustomizer {
+import java.util.Map;
- public EclipselinkJpaCustomizer() {
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class EclipselinkJpaCustomizer implements JpaCustomizer {
+ /**
+ * Creates a new EclipselinkJpaCustomizer object.
+ */
+ public EclipselinkJpaCustomizer() {
// Empty
}
-
+
@Override
- public void customize(PersistenceUnitDescription aPersistenceUnit, Map<String, String> aJpaProperties) {
+ public void customize(PersistenceUnitDescription aPersistenceUnit,
+ Map<String, String> aJpaProperties) {
// Hack to make JNDI lookup of the datasource work with toplink
- aJpaProperties.put("eclipselink.session.customizer", JndiSessionCustomizer.class
- .getName());
-
+ aJpaProperties.put("eclipselink.session.customizer",
+ JndiSessionCustomizer.class.getName());
+
// DDL generation for toplink
- aJpaProperties.put("eclipselink.ddl-generation", "create-tables");
+ aJpaProperties.put("eclipselink.ddl-generation", "create-tables");
}
-
+
@Override
public ITableFilterSimple getJpaTables() {
return new EclipselinkTables();
}
-
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.eclipselink;
-import java.util.Arrays;
-import java.util.List;
-
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.filter.ITableFilterSimple;
+import java.util.Arrays;
+import java.util.List;
+
/**
- * Toplink-specific tables.
+ * Toplink-specific tables.
*/
public class EclipselinkTables implements ITableFilterSimple {
+ private static final List<String> TABLES = Arrays
+ .asList(new String[] { "SEQUENCE" });
- private static final List<String> TABLES = Arrays.asList(new String[] { "SEQUENCE" } );
-
- public boolean accept(String aTableName) throws DataSetException {
- return TABLES.contains(aTableName);
- }
-
+ public boolean accept(String aTableName) throws DataSetException {
+ return TABLES.contains(aTableName);
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.eclipselink;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-
import org.eclipse.persistence.config.SessionCustomizer;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.server.ServerSession;
-
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
/**
- * See http://wiki.eclipse.org/Customizing_the_EclipseLink_Application_(ELUG) Use for clients that would like to use a
- * JTA SE pu instead of a RESOURCE_LOCAL SE pu.
- *
- * This utility also makes sure that using a persistence.xml with a JTA datasource works in a standalone Java SE
- * environment together with our JNDI stub.
+ * See http://wiki.eclipse.org/Customizing_the_EclipseLink_Application_(ELUG)
+ * Use for clients that would like to use a JTA SE pu instead of a
+ * RESOURCE_LOCAL SE pu. This utility also makes sure that using a
+ * persistence.xml with a JTA datasource works in a standalone Java SE
+ * environment together with our JNDI stub.
*/
-public class JndiSessionCustomizer
- implements SessionCustomizer {
-
- public JndiSessionCustomizer() {
- // Empty.
- }
-
- /**
- * Get a dataSource connection and set it on the session with lookupType=STRING_LOOKUP
- */
- public void customize(Session session) throws Exception {
- JNDIConnector connector = null;
- Context context = null;
- try {
- context = new InitialContext();
- if(null != context) {
- connector = (JNDIConnector)session.getLogin().getConnector(); // possible CCE
- // Change from COMPOSITE_NAME_LOOKUP to STRING_LOOKUP
- // Note: if both jta and non-jta elements exist this will only change the first one - and may still result in
- // the COMPOSITE_NAME_LOOKUP being set
- // Make sure only jta-data-source is in persistence.xml with no non-jta-data-source property set
- connector.setLookupType(JNDIConnector.STRING_LOOKUP);
-
- // Or, if you are specifying both JTA and non-JTA in your persistence.xml then set both connectors to be safe
- JNDIConnector writeConnector = (JNDIConnector)session.getLogin().getConnector();
- writeConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
- JNDIConnector readConnector =
- (JNDIConnector)((DatabaseLogin)((ServerSession)session).getReadConnectionPool().getLogin()).getConnector();
- readConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
-
- System.out.println("JndiSessionCustomizer: configured " + connector.getName());
- }
- else {
- throw new Exception("JndiSessionCustomizer: Context is null");
- }
+public class JndiSessionCustomizer implements SessionCustomizer {
+ /**
+ * Creates a new JndiSessionCustomizer object.
+ */
+ public JndiSessionCustomizer() {
+ // Empty.
}
- catch(Exception e) {
- e.printStackTrace();
+
+ /**
+ * Get a dataSource connection and set it on the session with
+ * lookupType=STRING_LOOKUP
+ *
+ *
+ */
+ public void customize(Session aSession) throws Exception {
+ JNDIConnector connector = null;
+ Context context = null;
+
+ try {
+ context = new InitialContext();
+
+ if (null != context) {
+ connector = (JNDIConnector) aSession.getLogin().getConnector(); // possible
+ // CCE
+ // Change from COMPOSITE_NAME_LOOKUP to STRING_LOOKUP
+ // Note: if both jta and non-jta elements exist this will only
+ // change the first one - and may still result in
+ // the COMPOSITE_NAME_LOOKUP being set
+ // Make sure only jta-data-source is in persistence.xml with no
+ // non-jta-data-source property set
+
+ connector.setLookupType(JNDIConnector.STRING_LOOKUP);
+
+ // Or, if you are specifying both JTA and non-JTA in your
+ // persistence.xml then set both connectors to be safe
+ JNDIConnector writeConnector = (JNDIConnector) aSession
+ .getLogin().getConnector();
+ writeConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
+
+ JNDIConnector readConnector = (JNDIConnector) ((DatabaseLogin) ((ServerSession) aSession)
+ .getReadConnectionPool().getLogin()).getConnector();
+ readConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
+
+ System.out.println("JndiSessionCustomizer: configured " +
+ connector.getName());
+ } else {
+ throw new Exception("JndiSessionCustomizer: Context is null");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- }
-}
\ No newline at end of file
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.eclipselink;
import static junit.framework.Assert.assertEquals;
-import javax.persistence.EntityManager;
-import javax.sql.DataSource;
-
import org.dbunit.IDatabaseTester;
+
import org.dbunit.dataset.ITable;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+
import org.wamblee.support.persistence.Database;
import org.wamblee.support.persistence.DatabaseBuilder;
import org.wamblee.support.persistence.DatabaseUtils;
import org.wamblee.support.persistence.DatabaseUtilsTestBase;
import org.wamblee.support.persistence.JpaBuilder;
-import org.wamblee.support.persistence.PersistenceUnitDescription;
import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
+import org.wamblee.support.persistence.PersistenceUnitDescription;
+
+import javax.persistence.EntityManager;
+
+import javax.sql.DataSource;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DatabaseUtilsTest extends DatabaseUtilsTestBase {
- // Empty, all tests inherited
+ // Empty, all tests inherited
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.eclipselink;
-import javax.persistence.EntityManager;
-import javax.persistence.Persistence;
-import javax.sql.DataSource;
+import static junit.framework.Assert.*;
import org.dbunit.DataSourceDatabaseTester;
import org.dbunit.DatabaseTestCase;
import org.dbunit.IDatabaseTester;
+
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.filter.ITableFilterSimple;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+
import org.wamblee.support.persistence.DatabaseUtils;
import org.wamblee.support.persistence.JpaBuilder;
+import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
import org.wamblee.support.persistence.JpaTester;
import org.wamblee.support.persistence.MyEntityExampleTestBase;
-import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
-import static junit.framework.Assert.*;
+import javax.persistence.EntityManager;
+import javax.persistence.Persistence;
+import javax.sql.DataSource;
/**
- * This class shows an example of how to test an entity using jpa.
+ * This class shows an example of how to test an entity using jpa.
*/
public class MyEntityExampleTest extends MyEntityExampleTestBase {
// Empty, all tests are inherited
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * Thread-specific proxy is used to create implementations of interfaces that
+ * delegate to a thread-specific implementation of the service.
+ *
+ * It is used for instance to pass a transaction scoped entity manager around.
+ *
+ * @param T
+ * Interface to proxy.
+ * @author Erik Brakkee
+ *
+ */
+public class ThreadSpecificProxyFactory<T> {
+ private class ThreadSpecificInvocationHandler implements InvocationHandler {
+
+ @Override
+ public Object invoke(Object aProxy, Method aMethod, Object[] aArgs)
+ throws Throwable {
+ try {
+ return aMethod.invoke(svc.get(), aArgs);
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ }
+ }
+ }
+
+ private ThreadLocal<T> svc = new ThreadLocal<T>();
+ private Class clazz;
+
+ /**
+ * Constructs the factory.
+ *
+ * @param aClass
+ * Interface class of the service to proxy.
+ */
+ public ThreadSpecificProxyFactory(Class<T> aClass) {
+ if (!aClass.isInterface()) {
+ throw new IllegalArgumentException("Class " + aClass.getName() +
+ " is not an interface");
+ }
+ clazz = aClass;
+ }
+
+ /**
+ * Sets the thread-specific service.
+ *
+ * @param aService
+ * Service, use null value to reset.
+ */
+ public void set(T aService) {
+ svc.set(aService);
+ }
+
+ /**
+ * Gets the proxy that delegates to the thread-specific instance set by
+ * {@link #set(Object)}
+ *
+ * @return Proxy.
+ */
+ public T getProxy() {
+ InvocationHandler handler = new ThreadSpecificInvocationHandler();
+ Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(),
+ new Class[] { clazz });
+ T proxy;
+ try {
+ proxy = (T) proxyClass.getConstructor(
+ new Class[] { InvocationHandler.class }).newInstance(
+ new Object[] { handler });
+ return proxy;
+ } catch (Exception e) {
+ throw new RuntimeException("Could not create proxy for " +
+ clazz.getName(), e);
+ }
+ }
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.jndi;
import java.util.HashMap;
import javax.naming.NamingException;
public class StubInitialContext extends InitialContext {
- private Map<String, Object> bindings = new HashMap<String, Object>();
+ private Map<String, Object> bindings = new HashMap<String, Object>();
- public StubInitialContext() throws NamingException {
- super(true);
- }
-
- @Override
- public void bind(String name, Object obj) throws NamingException {
- bindings.put(name, obj);
- }
+ public StubInitialContext() throws NamingException {
+ super(true);
+ }
- @Override
- public Object lookup(String name) throws NamingException {
- return bindings.get(name);
- }
-
- @Override
- public Object lookup(Name name) throws NamingException {
- return super.lookup(name.toString());
- }
+ @Override
+ public void bind(String aName, Object aObj) throws NamingException {
+ bindings.put(aName, aObj);
+ }
+
+ @Override
+ public Object lookup(String aName) throws NamingException {
+ return bindings.get(aName);
+ }
+
+ @Override
+ public Object lookup(Name aName) throws NamingException {
+ return super.lookup(aName.toString());
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.jndi;
-import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Map;
import javax.naming.Context;
-import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
*/
public class StubInitialContextFactory implements InitialContextFactory {
- private static Context context;
-
- private static void initialize() {
- try {
- context = new StubInitialContext();
- } catch (NamingException e) { // can't happen.
- throw new RuntimeException(e);
- }
- }
-
- /**
- * This method must be called to register this initial context factory as
- * the default implementation for JNDI.
- *
- * @throws Exception
- */
- public static void register() {
- // sets up the InitialContextFactoryForTest as default factory.
- System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
- StubInitialContextFactory.class.getName());
- if (context == null) {
- initialize();
- }
- }
-
- /**
- * Unregisters the initial context factory
- */
- public static void unregister() {
- System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "");
- context = null;
- }
-
- public Context getInitialContext(Hashtable<?, ?> environment)
- throws NamingException {
- return context;
- }
+ private static Context CONTEXT;
+
+ private static void initialize() {
+ try {
+ CONTEXT = new StubInitialContext();
+ } catch (NamingException e) { // can't happen.
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * This method must be called to register this initial context factory as
+ * the default implementation for JNDI.
+ *
+ * @throws Exception
+ */
+ public static void register() {
+ // sets up the InitialContextFactoryForTest as default factory.
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+ StubInitialContextFactory.class.getName());
+ if (CONTEXT == null) {
+ initialize();
+ }
+ }
+
+ /**
+ * Unregisters the initial context factory
+ */
+ public static void unregister() {
+ System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "");
+ CONTEXT = null;
+ }
+
+ public Context getInitialContext(Hashtable<?, ?> aEnvironment)
+ throws NamingException {
+ return CONTEXT;
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import javax.sql.DataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
public abstract class AbstractDatabase implements Database {
- private static final int CONNECTION_POOL_SIZE = 16;
+ private static final int CONNECTION_POOL_SIZE = 16;
- private DataSource itsDataSource;
-
- private boolean started;
-
- protected AbstractDatabase() {
- started = false;
- }
-
- protected abstract void doStart();
-
- protected abstract void doStop();
-
- /**
- * This method must be called from the start method.
- */
- protected final void createDataSource() {
- GenericObjectPool connectionPool = new GenericObjectPool(null);
- connectionPool.setMaxActive(CONNECTION_POOL_SIZE);
- ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(getJdbcUrl(), getUsername(), getPassword());
- // The following line must be kept in although it does not appear to be used, the constructor regsiters the
- // constructed object at the connection pool.
- PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
- itsDataSource = new PoolingDataSource(connectionPool);
- }
-
-
- /// BELOW THIS LINE IS NOT OF INTEREST TO SUBCLASSES.
-
- public final DataSource start() {
- if ( started ) {
- throw new RuntimeException("Database already started");
- }
- started = true;
- doStart();
- return getDatasource();
- }
-
- public final void stop() {
- if ( ! started ) {
- return; // nothing to do.
- }
- started = false;
- doStop();
- }
+ private DataSource itsDataSource;
- private final DataSource getDatasource() {
- if ( !started) {
- throw new RuntimeException("Database is not started!");
- }
- return itsDataSource;
- }
-
- protected String getProperty(String aName) {
- String value = System.getProperty(aName);
- if ( value != null ) {
- return value;
- }
- value = System.getenv(aName);
- if ( value != null ) {
- return value;
- }
- throw new RuntimeException("This class expects the '" + aName + "' property to be set");
- }
+ private boolean started;
+
+ protected AbstractDatabase() {
+ started = false;
+ }
+
+ protected abstract void doStart();
+
+ protected abstract void doStop();
+
+ /**
+ * This method must be called from the start method.
+ */
+ protected final void createDataSource() {
+ GenericObjectPool connectionPool = new GenericObjectPool(null);
+ connectionPool.setMaxActive(CONNECTION_POOL_SIZE);
+ ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
+ getJdbcUrl(), getUsername(), getPassword());
+ // The following line must be kept in although it does not appear to be
+ // used, the constructor regsiters the
+ // constructed object at the connection pool.
+ PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(
+ connectionFactory, connectionPool, null, null, false, true);
+ ingoredVariable(poolableConnectionFactory);
+ itsDataSource = new PoolingDataSource(connectionPool);
+ }
+
+ private static void ingoredVariable(PoolableConnectionFactory aFactory) {
+ // Empty
+ }
+
+ // / BELOW THIS LINE IS NOT OF INTEREST TO SUBCLASSES.
+
+ public final DataSource start() {
+ if (started) {
+ throw new RuntimeException("Database already started");
+ }
+ started = true;
+ doStart();
+ return getDatasource();
+ }
+
+ public final void stop() {
+ if (!started) {
+ return; // nothing to do.
+ }
+ started = false;
+ doStop();
+ }
+
+ private final DataSource getDatasource() {
+ if (!started) {
+ throw new RuntimeException("Database is not started!");
+ }
+ return itsDataSource;
+ }
+
+ protected String getProperty(String aName) {
+ String value = System.getProperty(aName);
+ if (value != null) {
+ return value;
+ }
+ value = System.getenv(aName);
+ if (value != null) {
+ return value;
+ }
+ throw new RuntimeException("This class expects the '" + aName +
+ "' property to be set");
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.List;
public abstract class AbstractDatabaseProvider implements DatabaseProvider {
- protected abstract List<String> getCapabilities();
+ protected abstract List<String> getCapabilities();
- public final boolean supportsCapabilities(String[] aCapabilities) {
- for (String capability: aCapabilities) {
- if ( !getCapabilities().contains(capability)) {
- return false;
- }
- }
- return true;
- }
+ public final boolean supportsCapabilities(String[] aCapabilities) {
+ for (String capability : aCapabilities) {
+ if (!getCapabilities().contains(capability)) {
+ return false;
+ }
+ }
+ return true;
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.List;
import org.dbunit.dataset.filter.ITableFilterSimple;
public class CompositeJpaCustomizer implements JpaCustomizer {
-
- private List<JpaCustomizer> _customizers;
- private CompositeJpaTables _tables;
-
- public CompositeJpaCustomizer(List<JpaCustomizer> aCustomizers) {
- _customizers = aCustomizers;
- _tables = new CompositeJpaTables();
- for (JpaCustomizer customizer: _customizers) {
- _tables.add(customizer.getJpaTables());
- }
+
+ private List<JpaCustomizer> customizers;
+ private CompositeJpaTables tables;
+
+ public CompositeJpaCustomizer(List<JpaCustomizer> aCustomizers) {
+ customizers = aCustomizers;
+ tables = new CompositeJpaTables();
+ for (JpaCustomizer customizer : customizers) {
+ tables.add(customizer.getJpaTables());
+ }
}
-
+
@Override
- public void customize(PersistenceUnitDescription aPersistenceUnit, Map<String, String> aJpaProperties) {
- for (JpaCustomizer customizer: _customizers) {
- customizer.customize(aPersistenceUnit, aJpaProperties);
+ public void customize(PersistenceUnitDescription aPersistenceUnit,
+ Map<String, String> aJpaProperties) {
+ for (JpaCustomizer customizer : customizers) {
+ customizer.customize(aPersistenceUnit, aJpaProperties);
}
}
@Override
public ITableFilterSimple getJpaTables() {
- return _tables;
+ return tables;
}
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.ArrayList;
import org.dbunit.dataset.filter.ITableFilterSimple;
public class CompositeJpaTables implements ITableFilterSimple {
-
- private List<ITableFilterSimple> _tables;
-
- public CompositeJpaTables() {
- _tables = new ArrayList<ITableFilterSimple>();
+
+ private List<ITableFilterSimple> tables;
+
+ public CompositeJpaTables() {
+ tables = new ArrayList<ITableFilterSimple>();
}
-
- public void add(ITableFilterSimple aFilter) {
- _tables.add(aFilter);
+
+ public void add(ITableFilterSimple aFilter) {
+ tables.add(aFilter);
}
@Override
public boolean accept(String aTableName) throws DataSetException {
- for (ITableFilterSimple filter: _tables) {
- if (filter.accept(aTableName)) {
- return true;
+ for (ITableFilterSimple filter : tables) {
+ if (filter.accept(aTableName)) {
+ return true;
}
}
- return false;
+ return false;
}
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.wamblee.support.persistence;
import javax.sql.DataSource;
* @author Erik Brakkee
*/
public interface Database {
-
+
/**
* Starts a database. This call should not block and return as soon as the
* database has been started.
*/
DataSource start();
-
+
/**
* Gets the Jdbc Url to connect to this database.
*
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.ArrayList;
/**
* DatabaseBuilder is used from unit test to obtain a reference to a database
* from unit test. This database is either an inmemory database or represents an
- * external database. Purpose of this utility is to make test code independent of the
- * particular database used and specifically to be able to run database tests without
- * any configuration at all (using an inmemory database).
+ * external database. Purpose of this utility is to make test code independent
+ * of the particular database used and specifically to be able to run database
+ * tests without any configuration at all (using an inmemory database).
*
* The type of database to use can be overridden by specifying either a system
* property or an environment variable ({@link #DB_CAPABILITIES_PROP}) that
* provides its own capabilities (see {@link DatabaseProvider} implementations}.
*
*
- * There are currently two database types available:
+ * There are currently two database types available:
* <ul>
- * <li> Derby: AN inmemory derby. Provided by {@link DerbyDatabaseProvider}. This is the default.
- * </li>
- * <li> External: An arbitrary external database configured using system properties or environment variables
- * in the usual way using a JDBC URL, username, and password.
- * </li>
+ * <li>Derby: AN inmemory derby. Provided by {@link DerbyDatabaseProvider}. This
+ * is the default.</li>
+ * <li>External: An arbitrary external database configured using system
+ * properties or environment variables in the usual way using a JDBC URL,
+ * username, and password.</li>
* </ul>
*
- * The <code>DatabaseBuilder</code> uses the {@link ServiceLoader} mechanism to find implementations
- * of {@link DatabaseProvider} on the classpath. In the {@link #getDatabase(String...)} method a number of
- * capabilities are passed. The database providers are then searched in (arbitrary) order and the first one that
- * has all required capabilities is returned.
+ * The <code>DatabaseBuilder</code> uses the {@link ServiceLoader} mechanism to
+ * find implementations of {@link DatabaseProvider} on the classpath. In the
+ * {@link #getDatabase(String...)} method a number of capabilities are passed.
+ * The database providers are then searched in (arbitrary) order and the first
+ * one that has all required capabilities is returned.
*
- * {@link #getSupportedDatabases()} gives a list of all available databases.
+ * {@link #getSupportedDatabases()} gives a list of all available databases.
*/
public class DatabaseBuilder {
- private static final Logger LOGGER = Logger.getLogger(DatabaseBuilder.class
- .getName());
-
- /**
- * Environmment variable by which capabilities of the requested database can
- * be defined
- */
- private static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES";
+ private static final Logger LOGGER = Logger.getLogger(DatabaseBuilder.class
+ .getName());
- private static ServiceLoader<DatabaseProvider> LOADER = null;
+ /**
+ * Environmment variable by which capabilities of the requested database can
+ * be defined
+ */
+ private static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES";
- private DatabaseBuilder() {
- // Empty.
- }
+ private static ServiceLoader<DatabaseProvider> LOADER =
+ ServiceLoader.load(DatabaseProvider.class);
- private static String[] parseCapabilities(String aValue) {
- return aValue.split(",");
- }
+ private DatabaseBuilder() {
+ // Empty.
+ }
- /**
- * Gets the first database that has all required capabilities.
- * @param aCapabilities Capabilities.
- * @return Database to use.
- */
- public static Database getDatabase(String... aCapabilities) {
- if (aCapabilities.length == 0) {
- LOGGER.info("Examining database capabilities");
- LOGGER.info(" Checking system property " + DB_CAPABILITIES_PROP);
- String capabilities = System.getProperty(DB_CAPABILITIES_PROP);
- if (capabilities != null) {
- aCapabilities = parseCapabilities(capabilities);
- } else {
- LOGGER.info(" Checking environment variable "
- + DB_CAPABILITIES_PROP);
- capabilities = System.getenv(DB_CAPABILITIES_PROP);
- if (capabilities != null) {
- aCapabilities = parseCapabilities(capabilities);
- } else {
- LOGGER.info(" Using default capabilities");
- aCapabilities = new String[] { DatabaseProvider.CAPABILITY_IN_MEMORY };
- }
- }
- LOGGER.info("Using capabilities: " + aCapabilities);
- }
- synchronized (DatabaseBuilder.class) {
- initLoader();
- for (DatabaseProvider db : LOADER) {
- if (db.supportsCapabilities(aCapabilities)) {
- return db.create();
- }
- }
- }
- throw new RuntimeException(
- "No database found that satisfies capabilities: "
- + Arrays.asList(aCapabilities));
- }
+ private static String[] parseCapabilities(String aValue) {
+ return aValue.split(",");
+ }
- /**
- * Gets a list of available databases.
- * @return List of databases.
- */
- public static List<DatabaseDescription> getSupportedDatabases() {
- initLoader();
- List<DatabaseDescription> descriptions = new ArrayList<DatabaseDescription>();
- for (DatabaseProvider db : LOADER) {
- descriptions.add(db.getDescription());
- }
- return descriptions;
- }
+ /**
+ * Gets the first database that has all required capabilities.
+ *
+ * @param aCapabilities
+ * Capabilities.
+ * @return Database to use.
+ */
+ public static Database getDatabase(String... aCapabilities) {
+ if (aCapabilities.length == 0) {
+ LOGGER.info("Examining database capabilities");
+ LOGGER.info(" Checking system property " + DB_CAPABILITIES_PROP);
+ String capabilities = System.getProperty(DB_CAPABILITIES_PROP);
+ if (capabilities != null) {
+ aCapabilities = parseCapabilities(capabilities);
+ } else {
+ LOGGER.info(" Checking environment variable " +
+ DB_CAPABILITIES_PROP);
+ capabilities = System.getenv(DB_CAPABILITIES_PROP);
+ if (capabilities != null) {
+ aCapabilities = parseCapabilities(capabilities);
+ } else {
+ LOGGER.info(" Using default capabilities");
+ aCapabilities = new String[] { DatabaseProvider.CAPABILITY_IN_MEMORY };
+ }
+ }
+ LOGGER.info("Using capabilities: " + Arrays.asList(aCapabilities));
+ }
+ synchronized (DatabaseBuilder.class) {
+ for (DatabaseProvider db : LOADER) {
+ if (db.supportsCapabilities(aCapabilities)) {
+ return db.create();
+ }
+ }
+ }
+ throw new RuntimeException(
+ "No database found that satisfies capabilities: " +
+ Arrays.asList(aCapabilities));
+ }
- private static void initLoader() {
- if (LOADER == null) {
- LOADER = ServiceLoader.load(DatabaseProvider.class);
- }
- }
+ /**
+ * Gets a list of available databases.
+ *
+ * @return List of databases.
+ */
+ public static List<DatabaseDescription> getSupportedDatabases() {
+ List<DatabaseDescription> descriptions = new ArrayList<DatabaseDescription>();
+ for (DatabaseProvider db : LOADER) {
+ descriptions.add(db.getDescription());
+ }
+ return descriptions;
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
/**
- * Description of a specific database.
+ * Description of a specific database.
*/
public class DatabaseDescription {
- private String[] itsCapabilities;
- private String itsDatabase;
- private String itsOther;
-
- /**
- * Constructs the description.
- * @param aCapabilities List of all capabilities.
- * @param aDatabase Database.
- * @param aOther Other information.
- */
- public DatabaseDescription(String[] aCapabilities, String aDatabase, String aOther) {
- itsCapabilities = aCapabilities;
- itsDatabase = aDatabase;
- itsOther = aOther;
- }
-
- @Override
- public String toString() {
- return "\n Database " + itsDatabase +
- "\n Capabilities: " + printCapabilities() +
- "\n Other info: " + itsOther;
- }
-
- private String printCapabilities() {
- String res = "";
- for (int i = 0; i < itsCapabilities.length; i++) {
- res += "" + itsCapabilities[i];
- if ( i < itsCapabilities.length -1 ) {
- res += ", ";
- }
- }
- return res;
- }
+ private String[] itsCapabilities;
+ private String itsDatabase;
+ private String itsOther;
+
+ /**
+ * Constructs the description.
+ *
+ * @param aCapabilities
+ * List of all capabilities.
+ * @param aDatabase
+ * Database.
+ * @param aOther
+ * Other information.
+ */
+ public DatabaseDescription(String[] aCapabilities, String aDatabase,
+ String aOther) {
+ itsCapabilities = aCapabilities;
+ itsDatabase = aDatabase;
+ itsOther = aOther;
+ }
+
+ @Override
+ public String toString() {
+ return "\n Database " + itsDatabase + "\n Capabilities: " +
+ printCapabilities() + "\n Other info: " + itsOther;
+ }
+
+ private String printCapabilities() {
+ StringBuffer res = new StringBuffer();
+ for (int i = 0; i < itsCapabilities.length; i++) {
+ res.append(itsCapabilities[i]);
+ if (i < itsCapabilities.length - 1) {
+ res.append(", ");
+ }
+ }
+ return res.toString();
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
/**
*/
public interface DatabaseProvider {
- /**
- * Capability that all databases that run inmemory have.
- */
- String CAPABILITY_IN_MEMORY = "INMEMORY";
+ /**
+ * Capability that all databases that run inmemory have.
+ */
+ String CAPABILITY_IN_MEMORY = "INMEMORY";
- /**
- * Capability that all databases that are external have.
- */
- String CAPABILITY_EXTERNAL = "EXTERNAL";
+ /**
+ * Capability that all databases that are external have.
+ */
+ String CAPABILITY_EXTERNAL = "EXTERNAL";
- /**
- * Determines if the database has all capabilities that are requested.
- * @param aCapabilities Capabilities it must ahve
- * @return True if it has all capabilities.
- */
- boolean supportsCapabilities(String[] aCapabilities);
+ /**
+ * Determines if the database has all capabilities that are requested.
+ *
+ * @param aCapabilities
+ * Capabilities it must ahve
+ * @return True if it has all capabilities.
+ */
+ boolean supportsCapabilities(String[] aCapabilities);
- /**
- * Gets the description for the database.
- * @return Description.
- */
- DatabaseDescription getDescription();
+ /**
+ * Gets the description for the database.
+ *
+ * @return Description.
+ */
+ DatabaseDescription getDescription();
- /**
- * Creates a database instance that represents a running instance of that database.
- * @return Database.
- */
- Database create();
+ /**
+ * Creates a database instance that represents a running instance of that
+ * database.
+ *
+ * @return Database.
+ */
+ Database create();
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.support.persistence;
-
/**
* This class is used for starting the database from ant.
*/
/**
* Database class which encapsulates management of the database.
*/
- private Class _databaseClass;
+ private Class databaseClass;
/**
* Execution as a main program. Commandline
* <pre>
*
* DatabaseStarter <databaseClassName>
- *
+ *
* </pre>
*
* where the database class name must be the name of a concrete subclass of
* {@link Database}.
*
- * @param args
+ * @param aArgs
*/
- public static void main( String[] args ) throws Exception {
- String clazz = args[0];
+ public static void main(String[] aArgs) throws Exception {
+ String clazz = aArgs[0];
try {
- new DatabaseStarter( Class.forName( clazz ) ).start( );
- } catch ( Exception e ) {
- e.printStackTrace( );
- System.out
- .println( "\nUsage: ant dbClass ");
+ new DatabaseStarter(Class.forName(clazz)).start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("\nUsage: ant dbClass ");
}
}
* Classname of the database class to use.
* @throws Exception
*/
- public DatabaseStarter( Class aClass ) throws Exception {
- if ( !Database.class.isAssignableFrom( aClass ) ) {
- throw new IllegalArgumentException( "Class '"
- + aClass.getName( )
- + "' is not a subclass of Database" );
+ public DatabaseStarter(Class aClass) throws Exception {
+ if (!Database.class.isAssignableFrom(aClass)) {
+ throw new IllegalArgumentException("Class '" + aClass.getName() +
+ "' is not a subclass of Database");
}
- _databaseClass = aClass;
+ databaseClass = aClass;
}
/**
*
* @throws Exception
*/
- public DatabaseStarter( ) throws Exception {
- this( DerbyDatabase.class );
+ public DatabaseStarter() throws Exception {
+ this(DerbyDatabase.class);
}
/**
*
* @throws Exception
*/
- public void start( ) throws Exception {
- Database lDatabase = (Database) _databaseClass.newInstance( );
- lDatabase.start( );
- System.out.println( "Database has been started. " );
- System.out.println( );
- System.out.println("=======================================================");
- System.out.println( "Connection details:" );
- // System.out.println( " Driver class: "
- // + lDatabase.getDriverClassName( ) );
- System.out.println( " JDBC URL: "
- + lDatabase.getExternalJdbcUrl( ) );
- System.out.println( " username: '" + lDatabase.getUsername( )
- + "'" );
- System.out.println( " password: '" + lDatabase.getPassword( )
- + "'" );
- System.out.println( "Interrupt the program to stop the database." );
- System.out.println("=======================================================");
- System.out.println("You must now populate the database with a schema. Use 'ant help' for information.");
- for ( ;; ) {
- Thread.sleep( 1000 );
+ public void start() throws Exception {
+ Database lDatabase = (Database) databaseClass.newInstance();
+ lDatabase.start();
+ System.out.println("Database has been started. ");
+ System.out.println();
+ System.out
+ .println("=======================================================");
+ System.out.println("Connection details:");
+ // System.out.println( " Driver class: "
+ // + lDatabase.getDriverClassName( ) );
+ System.out.println(" JDBC URL: " + lDatabase.getExternalJdbcUrl());
+ System.out.println(" username: '" + lDatabase.getUsername() + "'");
+ System.out.println(" password: '" + lDatabase.getPassword() + "'");
+ System.out.println("Interrupt the program to stop the database.");
+ System.out
+ .println("=======================================================");
+ System.out
+ .println("You must now populate the database with a schema. Use 'ant help' for information.");
+ for (;;) {
+ Thread.sleep(1000);
}
}
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.sql.Connection;
*/
public class DatabaseUtils {
- public static interface TableSet {
- boolean contains(String aTableName);
- }
-
- public static interface JdbcUnitOfWork<T> {
- T execute(Connection aConnection) throws Exception;
- }
-
- public static interface TableSetOperation {
- void execute(String aTable) throws Exception;
- }
-
- private static final Logger LOG = Logger.getLogger(DatabaseUtils.class
- .getName());
-
- /**
- * Schema pattern.
- */
- private static final String SCHEMA_PATTERN = "%";
- private DataSource dataSource;
- private ITableFilterSimple tables;
-
-
- public DatabaseUtils(DataSource aDataSource, ITableFilterSimple aTables) {
- dataSource = aDataSource;
- tables = aTables;
- }
-
- public IDatabaseTester createDbTester() throws Exception {
- return createDbTester(getTableNames(tables));
- }
-
- public IDatabaseTester createDbTester(String[] aTables) throws Exception {
- IDatabaseTester dbtester = new DataSourceDatabaseTester(dataSource);
- dbtester.setDataSet(dbtester.getConnection().createDataSet(aTables));
- return dbtester;
- }
-
- public void cleanDatabase() throws Exception {
- cleanDatabase(tables);
- }
-
- public void executeOnTables(ITableFilterSimple aTables,
- final TableSetOperation aOperation) throws Exception {
- final String[] tables = getTableNames(aTables);
- executeInTransaction(new JdbcUnitOfWork<Void>() {
- public Void execute(Connection aConnection) throws Exception {
- for (int i = tables.length - 1; i >= 0; i--) {
- aOperation.execute(tables[i]);
- }
- return null;
- }
- });
- for (String table : tables) {
-
- }
- }
-
- public void cleanDatabase(ITableFilterSimple aSelection) throws Exception {
-
- final String[] tables = getTableNames(aSelection);
- executeInTransaction(new JdbcUnitOfWork<Void>() {
-
- public Void execute(Connection aConnection) throws Exception {
- IDatabaseConnection connection = new DatabaseConnection(
- aConnection);
- ITableFilter filter = new DatabaseSequenceFilter(connection,
- tables);
- IDataSet dataset = new FilteredDataSet(filter, connection
- .createDataSet(tables));
- DatabaseOperation.DELETE_ALL.execute(connection, dataset);
- return null;
- }
- });
-
- }
-
- public <T> T executeInTransaction(JdbcUnitOfWork<T> aCallback)
- throws Exception {
- Connection connection = dataSource.getConnection();
- try {
- T value = aCallback.execute(connection);
- connection.commit();
- return value;
- } finally {
- connection.close();
- }
- }
-
- public String[] getTableNames() throws Exception {
- return getTableNames(tables);
- }
-
- /**
- * @throws SQLException
- */
- public String[] getTableNames(ITableFilterSimple aSelection)
- throws Exception {
-
- List<String> result = new ArrayList<String>();
- LOG.fine("Getting database table names to clean (schema: '"
- + SCHEMA_PATTERN + "'");
-
- ResultSet tables = dataSource.getConnection().getMetaData().getTables(
- null, SCHEMA_PATTERN, "%", new String[] { "TABLE" });
- while (tables.next()) {
- String table = tables.getString("TABLE_NAME");
- if (aSelection.accept(table)) {
- result.add(table);
- }
- }
- return (String[]) result.toArray(new String[0]);
- }
-
- public void emptyTables() throws Exception {
- executeOnTables(tables, new TableSetOperation() {
- public void execute(String aTable) throws Exception {
- emptyTable(aTable);
- }
- });
- }
-
- /**
- * @return
- * @throws SQLException
- */
- public void emptyTables(final ITableFilterSimple aSelection)
- throws Exception {
- executeOnTables(aSelection, new TableSetOperation() {
- public void execute(String aTable) throws Exception {
- emptyTable(aTable);
- }
- });
- }
-
- /**
- * @return
- * @throws SQLException
- */
- public void emptyTable(String aTable) throws Exception {
- executeSql("delete from " + aTable);
- }
-
- public void dropTables() throws Exception {
- executeOnTables(tables, new TableSetOperation() {
-
- public void execute(String aTable) throws Exception {
- dropTable(aTable);
- }
- });
- }
-
-
- public void dropTables(ITableFilterSimple aTables) throws Exception {
- executeOnTables(aTables, new TableSetOperation() {
-
- public void execute(String aTable) throws Exception {
- dropTable(aTable);
- }
- });
- }
-
- /**
- * @return
- * @throws SQLException
- */
- public void dropTable(final String aTable) throws Exception {
- executeInTransaction(new JdbcUnitOfWork<Void>() {
- public Void execute(Connection aConnection) throws Exception {
- executeUpdate(aConnection, "drop table " + aTable);
- return null;
- }
- });
-
- }
-
- /**
- * Executes an SQL statement within a transaction.
- *
- * @param aSql
- * SQL statement.
- * @return Return code of the corresponding JDBC call.
- */
- public int executeSql(final String aSql) throws Exception {
- return executeSql(aSql, new Object[0]);
- }
-
- /**
- * Executes an SQL statement within a transaction. See
- * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
- * supported argument types.
- *
- * @param aSql
- * SQL statement.
- * @param aArg
- * Argument of the sql statement.
- * @return Return code of the corresponding JDBC call.
- */
- public int executeSql(final String aSql, final Object aArg)
- throws Exception {
- return executeSql(aSql, new Object[] { aArg });
- }
-
- /**
- * Executes an sql statement. See
- * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
- * supported argument types.
- *
- * @param aSql
- * SQL query to execute.
- * @param aArgs
- * Arguments.
- * @return Number of rows updated.
- */
- public int executeSql(final String aSql, final Object[] aArgs)
- throws Exception {
- return executeInTransaction(new JdbcUnitOfWork<Integer>() {
- public Integer execute(Connection aConnection) throws Exception {
- PreparedStatement stmt = aConnection.prepareStatement(aSql);
- setPreparedParams(aArgs, stmt);
- return stmt.executeUpdate();
- }
- });
- }
-
- /**
- * Executes an SQL query.
- *
- * @param aSql
- * Query to execute.
- * @return Result set.
- */
- public ResultSet executeQuery(Connection aConnection, String aSql) {
- return executeQuery(aConnection, aSql, new Object[0]);
- }
-
- /**
- * Executes a query with a single argument. See
- * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
- * supported argument types.
- *
- * @param aSql
- * Query.
- * @param aArg
- * Argument.
- * @return Result set.
- */
- public ResultSet executeQuery(Connection aConnection, String aSql,
- Object aArg) {
- return executeQuery(aConnection, aSql, new Object[] { aArg });
- }
-
- /**
- * Executes a query. See
- * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
- * supported argument types.
- *
- * @param aSql
- * Sql query.
- * @param aArgs
- * Arguments to the query.
- * @return Result set.
- */
- public ResultSet executeQuery(Connection aConnection, final String aSql,
- final Object[] aArgs) {
- try {
- PreparedStatement statement = aConnection.prepareStatement(aSql);
- setPreparedParams(aArgs, statement);
-
- return statement.executeQuery();
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- public int executeUpdate(Connection aConnection, final String aSql,
- final Object... aArgs) {
- try {
- PreparedStatement statement = aConnection.prepareStatement(aSql);
- setPreparedParams(aArgs, statement);
-
- return statement.executeUpdate();
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Sets the values of a prepared statement. See
- * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
- * supported argument types.
- *
- * @param aArgs
- * Arguments to the prepared statement.
- * @param aStatement
- * Prepared statement
- * @throws SQLException
- */
- private void setPreparedParams(final Object[] aArgs,
- PreparedStatement aStatement) throws SQLException {
- for (int i = 1; i <= aArgs.length; i++) {
- setPreparedParam(i, aStatement, aArgs[i - 1]);
- }
- }
-
- /**
- * Sets a prepared statement parameter.
- *
- * @param aIndex
- * Index of the parameter.
- * @param aStatement
- * Prepared statement.
- * @param aObject
- * Value Must be of type Integer, Long, or String.
- * @throws SQLException
- */
- private void setPreparedParam(int aIndex, PreparedStatement aStatement,
- Object aObject) throws SQLException {
- if (aObject instanceof Integer) {
- aStatement.setInt(aIndex, ((Integer) aObject).intValue());
- } else if (aObject instanceof Long) {
- aStatement.setLong(aIndex, ((Integer) aObject).longValue());
- } else if (aObject instanceof String) {
- aStatement.setString(aIndex, (String) aObject);
- } else {
- TestCase.fail("Unsupported object type for prepared statement: "
- + aObject.getClass() + " value: " + aObject
- + " statement: " + aStatement);
- }
- }
-
- /**
- * @return
- * @throws SQLException
- */
- public int getTableSize(final String aTable) throws Exception {
- return executeInTransaction(new JdbcUnitOfWork<Integer>() {
- public Integer execute(Connection aConnection) throws Exception {
- ResultSet resultSet = executeQuery(aConnection,
- "select count(*) from " + aTable);
- resultSet.next();
- return resultSet.getInt(1);
- }
- });
-
- }
-
- public int countResultSet(ResultSet aResultSet) throws SQLException {
- int count = 0;
-
- while (aResultSet.next()) {
- count++;
- }
-
- return count;
- }
+ public static interface TableSet {
+ boolean contains(String aTableName);
+ }
+
+ public static interface JdbcUnitOfWork<T> {
+ T execute(Connection aConnection) throws Exception;
+ }
+
+ public static interface TableSetOperation {
+ void execute(String aTable) throws Exception;
+ }
+
+ private static final Logger LOG = Logger.getLogger(DatabaseUtils.class
+ .getName());
+
+ /**
+ * Schema pattern.
+ */
+ private static final String SCHEMA_PATTERN = "%";
+ private DataSource dataSource;
+ private ITableFilterSimple tables;
+
+ public DatabaseUtils(DataSource aDataSource, ITableFilterSimple aTables) {
+ dataSource = aDataSource;
+ tables = aTables;
+ }
+
+ public IDatabaseTester createDbTester() throws Exception {
+ return createDbTester(getTableNames(tables));
+ }
+
+ public IDatabaseTester createDbTester(String[] aTables) throws Exception {
+ IDatabaseTester dbtester = new DataSourceDatabaseTester(dataSource);
+ dbtester.setDataSet(dbtester.getConnection().createDataSet(aTables));
+ return dbtester;
+ }
+
+ public void cleanDatabase() throws Exception {
+ cleanDatabase(tables);
+ }
+
+ public void executeOnTables(ITableFilterSimple aTables,
+ final TableSetOperation aOperation) throws Exception {
+ final String[] tables = getTableNames(aTables);
+ executeInTransaction(new JdbcUnitOfWork<Void>() {
+ public Void execute(Connection aConnection) throws Exception {
+ for (int i = tables.length-1; i >= 0; i--) {
+ aOperation.execute(tables[i]);
+ }
+ return null;
+ }
+ });
+ }
+
+ public void cleanDatabase(ITableFilterSimple aSelection) throws Exception {
+
+ final String[] tables = getTableNames(aSelection);
+ executeInTransaction(new JdbcUnitOfWork<Void>() {
+
+ public Void execute(Connection aConnection) throws Exception {
+ IDatabaseConnection connection = new DatabaseConnection(
+ aConnection);
+ ITableFilter filter = new DatabaseSequenceFilter(connection,
+ tables);
+ IDataSet dataset = new FilteredDataSet(filter, connection
+ .createDataSet(tables));
+ DatabaseOperation.DELETE_ALL.execute(connection, dataset);
+ return null;
+ }
+ });
+
+ }
+
+ public <T> T executeInTransaction(JdbcUnitOfWork<T> aCallback)
+ throws Exception {
+ Connection connection = dataSource.getConnection();
+ try {
+ T value = aCallback.execute(connection);
+ connection.commit();
+ return value;
+ } finally {
+ connection.close();
+ }
+ }
+
+ public String[] getTableNames() throws Exception {
+ return getTableNames(tables);
+ }
+
+ /**
+ * @throws SQLException
+ */
+ public String[] getTableNames(ITableFilterSimple aSelection)
+ throws Exception {
+
+ List<String> result = new ArrayList<String>();
+ LOG.fine("Getting database table names to clean (schema: '" +
+ SCHEMA_PATTERN + "'");
+
+ Connection connection = dataSource.getConnection();
+ try {
+ ResultSet tables = connection.getMetaData().getTables(null,
+ SCHEMA_PATTERN, "%", new String[] { "TABLE" });
+ while (tables.next()) {
+ String table = tables.getString("TABLE_NAME");
+ if (aSelection.accept(table)) {
+ result.add(table);
+ }
+ }
+ return (String[]) result.toArray(new String[0]);
+ } finally {
+ connection.close();
+ }
+ }
+
+ public void emptyTables() throws Exception {
+ executeOnTables(tables, new TableSetOperation() {
+ public void execute(String aTable) throws Exception {
+ emptyTable(aTable);
+ }
+ });
+ }
+
+ /**
+ * @return
+ * @throws SQLException
+ */
+ public void emptyTables(final ITableFilterSimple aSelection)
+ throws Exception {
+ executeOnTables(aSelection, new TableSetOperation() {
+ public void execute(String aTable) throws Exception {
+ emptyTable(aTable);
+ }
+ });
+ }
+
+ /**
+ * @return
+ * @throws SQLException
+ */
+ public void emptyTable(String aTable) throws Exception {
+ executeSql("delete from " + aTable);
+ }
+
+ public void dropTables() throws Exception {
+ dropTables(tables);
+ }
+
+ public void dropTables(ITableFilterSimple aTables) throws Exception {
+ final String[] tables = getTableNames(aTables);
+ String[] sortedTables = executeInTransaction(new JdbcUnitOfWork<String[]>() {
+
+ public String[] execute(Connection aConnection) throws Exception {
+ IDatabaseConnection connection = new DatabaseConnection(
+ aConnection);
+ ITableFilter filter = new DatabaseSequenceFilter(connection,
+ tables);
+ IDataSet dataset = new FilteredDataSet(filter, connection
+ .createDataSet(tables));
+ return dataset.getTableNames();
+ }
+ });
+ for (int i = sortedTables.length-1; i >= 0; i--) {
+ dropTable(sortedTables[i]);
+ }
+ }
+
+ /**
+ * @return
+ * @throws SQLException
+ */
+ public void dropTable(final String aTable) throws Exception {
+ executeInTransaction(new JdbcUnitOfWork<Void>() {
+ public Void execute(Connection aConnection) throws Exception {
+ executeUpdate(aConnection, "drop table " + aTable);
+ return null;
+ }
+ });
+
+ }
+
+ /**
+ * Executes an SQL statement within a transaction.
+ *
+ * @param aSql
+ * SQL statement.
+ * @return Return code of the corresponding JDBC call.
+ */
+ public int executeSql(final String aSql) throws Exception {
+ return executeSql(aSql, new Object[0]);
+ }
+
+ /**
+ * Executes an SQL statement within a transaction. See
+ * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
+ * supported argument types.
+ *
+ * @param aSql
+ * SQL statement.
+ * @param aArg
+ * Argument of the sql statement.
+ * @return Return code of the corresponding JDBC call.
+ */
+ public int executeSql(final String aSql, final Object aArg)
+ throws Exception {
+ return executeSql(aSql, new Object[] { aArg });
+ }
+
+ /**
+ * Executes an sql statement. See
+ * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
+ * supported argument types.
+ *
+ * @param aSql
+ * SQL query to execute.
+ * @param aArgs
+ * Arguments.
+ * @return Number of rows updated.
+ */
+ public int executeSql(final String aSql, final Object[] aArgs)
+ throws Exception {
+ return executeInTransaction(new JdbcUnitOfWork<Integer>() {
+ public Integer execute(Connection aConnection) throws Exception {
+ PreparedStatement stmt = aConnection.prepareStatement(aSql);
+ setPreparedParams(aArgs, stmt);
+ return stmt.executeUpdate();
+ }
+ });
+ }
+
+ /**
+ * Executes an SQL query.
+ *
+ * @param aSql
+ * Query to execute.
+ * @return Result set.
+ */
+ public ResultSet executeQuery(Connection aConnection, String aSql) {
+ return executeQuery(aConnection, aSql, new Object[0]);
+ }
+
+ /**
+ * Executes a query with a single argument. See
+ * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
+ * supported argument types.
+ *
+ * @param aSql
+ * Query.
+ * @param aArg
+ * Argument.
+ * @return Result set.
+ */
+ public ResultSet executeQuery(Connection aConnection, String aSql,
+ Object aArg) {
+ return executeQuery(aConnection, aSql, new Object[] { aArg });
+ }
+
+ /**
+ * Executes a query. See
+ * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
+ * supported argument types.
+ *
+ * @param aSql
+ * Sql query.
+ * @param aArgs
+ * Arguments to the query.
+ * @return Result set.
+ */
+ public ResultSet executeQuery(Connection aConnection, final String aSql,
+ final Object[] aArgs) {
+ try {
+ PreparedStatement statement = aConnection.prepareStatement(aSql);
+ setPreparedParams(aArgs, statement);
+
+ return statement.executeQuery();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public int executeUpdate(Connection aConnection, final String aSql,
+ final Object... aArgs) {
+ try {
+ PreparedStatement statement = aConnection.prepareStatement(aSql);
+ setPreparedParams(aArgs, statement);
+
+ return statement.executeUpdate();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Sets the values of a prepared statement. See
+ * {@link #setPreparedParam(int, PreparedStatement, Object)}for details on
+ * supported argument types.
+ *
+ * @param aArgs
+ * Arguments to the prepared statement.
+ * @param aStatement
+ * Prepared statement
+ * @throws SQLException
+ */
+ private void setPreparedParams(final Object[] aArgs,
+ PreparedStatement aStatement) throws SQLException {
+ for (int i = 1; i <= aArgs.length; i++) {
+ setPreparedParam(i, aStatement, aArgs[i - 1]);
+ }
+ }
+
+ /**
+ * Sets a prepared statement parameter.
+ *
+ * @param aIndex
+ * Index of the parameter.
+ * @param aStatement
+ * Prepared statement.
+ * @param aObject
+ * Value Must be of type Integer, Long, or String.
+ * @throws SQLException
+ */
+ private void setPreparedParam(int aIndex, PreparedStatement aStatement,
+ Object aObject) throws SQLException {
+ if (aObject instanceof Integer) {
+ aStatement.setInt(aIndex, ((Integer) aObject).intValue());
+ } else if (aObject instanceof Long) {
+ aStatement.setLong(aIndex, ((Long) aObject).longValue());
+ } else if (aObject instanceof String) {
+ aStatement.setString(aIndex, (String) aObject);
+ } else {
+ TestCase.fail("Unsupported object type for prepared statement: " +
+ aObject.getClass() + " value: " + aObject + " statement: " +
+ aStatement);
+ }
+ }
+
+ /**
+ * @return
+ * @throws SQLException
+ */
+ public int getTableSize(final String aTable) throws Exception {
+ return executeInTransaction(new JdbcUnitOfWork<Integer>() {
+ public Integer execute(Connection aConnection) throws Exception {
+ ResultSet resultSet = executeQuery(aConnection,
+ "select count(*) from " + aTable);
+ resultSet.next();
+ return resultSet.getInt(1);
+ }
+ });
+
+ }
+
+ public int countResultSet(ResultSet aResultSet) throws SQLException {
+ int count = 0;
+
+ while (aResultSet.next()) {
+ count++;
+ }
+
+ return count;
+ }
}
/*
- * Copyright 2005 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
public class DerbyDatabase extends AbstractDatabase {
- /**
- * Logger.
- */
- private static final Logger LOGGER = Logger.getLogger(DerbyDatabase.class
- .getName());
-
- /**
- * Database user name.
- */
- private static final String USERNAME = "sa";
-
- /**
- * Database password.
- */
- private static final String PASSWORD = "123";
- /**
- * Poll interval for the checking the server status.
- */
- private static final int POLL_INTERVAL = 100;
-
- /**
- * Maximum time to wait until the server has started or stopped.
- */
- private static final int MAX_WAIT_TIME = 10000;
-
- /**
- * Database name to use.
- */
- private static final String DATABASE_NAME = "testdb";
-
- /**
- * Path on the file system where derby files are stored.
- */
- private static final String DATABASE_PATH = "target/db/persistence/derby";
-
- /**
- * Derby property required to set the file system path
- * {@link #DATABASE_PATH}.
- */
- private static final String SYSTEM_PATH_PROPERTY = "derby.system.home";
-
-
- private boolean inmemory;
-
-
- /**
- * Constructs derby database class to allow creation of derby database
- * instances.
- */
- public DerbyDatabase() {
- inmemory = true;
- }
-
- public DerbyDatabase(boolean aInMemoryFlag) {
- inmemory = aInMemoryFlag;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#start()
- */
- public void doStart() {
- try {
- // just in case a previous run was killed without the
- // cleanup
- cleanPersistentStorage();
-
- if (!inmemory) {
- // set database path.
- Properties lProperties = System.getProperties();
- lProperties.put(SYSTEM_PATH_PROPERTY, DATABASE_PATH);
- }
-
- Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
-
- runDatabase();
-
- waitUntilStartedOrStopped(true);
-
- // Force creation of the database.
- Connection lConnection = createConnection();
- lConnection.close();
-
- LOGGER.info("Database started: \n URL = " + getExternalJdbcUrl() + "\n user = " + getUsername() + "\n password = "
- + getPassword());
-
- createDataSource();
-
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- if (isStarted()) {
- LOGGER.warning("Shutting down db");
- DerbyDatabase.this.stop();
- }
- }
- });
- } catch (Exception e) {
- throw new RuntimeException("Problem starting database", e);
- }
- }
-
- /**
- * Waits until the database server has started or stopped.
- *
- * @param aStarted
- * If true, waits until the server is up, if false, waits until
- * the server is down.
- * @throws InterruptedException
- */
- private void waitUntilStartedOrStopped(boolean aStarted)
- throws InterruptedException {
- long lWaited = 0;
-
- while (aStarted != isStarted()) {
- Thread.sleep(POLL_INTERVAL);
- lWaited += POLL_INTERVAL;
-
- if (lWaited > MAX_WAIT_TIME) {
- throw new RuntimeException(
- "Derby database did not start within " + MAX_WAIT_TIME
- + "ms");
- }
- }
- }
-
- /**
- * Checks if the database server has started or not.
- *
- * @return True if started, false otherwise.
- */
- private boolean isStarted() {
- try {
- getControl().ping();
-
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- /**
- * Gets the controller for the database server.
- *
- * @return Controller.
- * @throws Exception
- */
- private NetworkServerControl getControl() throws Exception {
- return new NetworkServerControl();
- }
-
- /**
- * Runs the database.
- *
- */
- private void runDatabase() {
- try {
- getControl().start(new PrintWriter(System.out));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#getJdbcUrl()
- */
- public String getJdbcUrl() {
- return getBaseJdbcUrl()
- + ";create=true;retrieveMessagesFromServerOnGetMessage=true;";
- }
-
- private String getBaseJdbcUrl() {
- return (inmemory ? "jdbc:derby:memory:": "jdbc:derby:") + DATABASE_NAME;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#getExternalJdbcUrl()
- */
- public String getExternalJdbcUrl() {
- return "jdbc:derby://localhost:1527/" + (inmemory ? "memory:" : "") + DATABASE_NAME;
- }
-
- /**
- * Shuts down the derby database and cleans up all created files.
- *
- */
- private void shutdownDerby() {
- try {
- DriverManager.getConnection("jdbc:derby:;shutdown=true");
- throw new RuntimeException("Derby did not shutdown, "
- + " should always throw exception at shutdown");
- } catch (Exception e) {
- LOGGER.info("Derby has been shut down.");
- }
- }
-
- /**
- * Gets the user name.
- */
- public String getUsername() {
- return USERNAME;
- }
-
- /**
- * Gets the password.
- *
- * @return
- */
- public String getPassword() {
- return PASSWORD;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.wamblee.persistence.Database#createConnection()
- */
- public Connection createConnection() throws SQLException {
- Connection c = DriverManager.getConnection(getJdbcUrl(), getUsername(),
- getPassword());
-
- return c;
- }
-
-
- /**
- * Stops the derby database and cleans up all derby files.
- */
- public void doStop() {
- try {
- // shutdown network server.
- getControl().shutdown();
- waitUntilStartedOrStopped(false);
-
- // shutdown inmemory access.
- shutdownDerby();
- cleanPersistentStorage();
- } catch (Exception e) {
- LOGGER.log(Level.WARNING, "Problem stopping database", e);
- }
- }
-
- /**
- * Cleans up persistent storage of Derby.
- */
- private void cleanPersistentStorage() {
- File lFile = new File(DATABASE_PATH);
-
- if (lFile.isFile()) {
- TestCase.fail("A regular file by the name " + DATABASE_PATH
- + " exists, clean this up first");
- }
-
- if (!lFile.isDirectory()) {
- return; // no-op already cleanup up.
- }
- FileSystemUtils.deleteDirRecursively(DATABASE_PATH);
- }
+ /**
+ * Logger.
+ */
+ private static final Logger LOGGER = Logger.getLogger(DerbyDatabase.class
+ .getName());
+
+ /**
+ * Database user name.
+ */
+ private static final String USERNAME = "sa";
+
+ /**
+ * Database password.
+ */
+ private static final String PASSWORD = "123";
+ /**
+ * Poll interval for the checking the server status.
+ */
+ private static final int POLL_INTERVAL = 100;
+
+ /**
+ * Maximum time to wait until the server has started or stopped.
+ */
+ private static final int MAX_WAIT_TIME = 10000;
+
+ /**
+ * Database name to use.
+ */
+ private static final String DATABASE_NAME = "testdb";
+
+ /**
+ * Path on the file system where derby files are stored.
+ */
+ private static final String DATABASE_PATH = "target/db/persistence/derby";
+
+ /**
+ * Derby property required to set the file system path
+ * {@link #DATABASE_PATH}.
+ */
+ private static final String SYSTEM_PATH_PROPERTY = "derby.system.home";
+
+ private boolean inmemory;
+
+ /**
+ * Constructs derby database class to allow creation of derby database
+ * instances.
+ */
+ public DerbyDatabase() {
+ inmemory = true;
+ }
+
+ public DerbyDatabase(boolean aInMemoryFlag) {
+ inmemory = aInMemoryFlag;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#start()
+ */
+ public void doStart() {
+ try {
+ // just in case a previous run was killed without the
+ // cleanup
+ cleanPersistentStorage();
+
+ if (!inmemory) {
+ // set database path.
+ Properties lProperties = System.getProperties();
+ lProperties.put(SYSTEM_PATH_PROPERTY, DATABASE_PATH);
+ }
+
+ Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
+
+ runDatabase();
+
+ waitUntilStartedOrStopped(true);
+
+ // Force creation of the database.
+ Connection lConnection = createConnection();
+ lConnection.close();
+
+ LOGGER.info("Database started: \n URL = " +
+ getExternalJdbcUrl() + "\n user = " + getUsername() +
+ "\n password = " + getPassword());
+
+ createDataSource();
+
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ if (isStarted()) {
+ LOGGER.warning("Shutting down db");
+ DerbyDatabase.this.stop();
+ }
+ }
+ });
+ } catch (Exception e) {
+ throw new RuntimeException("Problem starting database", e);
+ }
+ }
+
+ /**
+ * Waits until the database server has started or stopped.
+ *
+ * @param aStarted
+ * If true, waits until the server is up, if false, waits until
+ * the server is down.
+ * @throws InterruptedException
+ */
+ private void waitUntilStartedOrStopped(boolean aStarted)
+ throws InterruptedException {
+ long lWaited = 0;
+
+ while (aStarted != isStarted()) {
+ Thread.sleep(POLL_INTERVAL);
+ lWaited += POLL_INTERVAL;
+
+ if (lWaited > MAX_WAIT_TIME) {
+ throw new RuntimeException(
+ "Derby database did not start within " + MAX_WAIT_TIME +
+ "ms");
+ }
+ }
+ }
+
+ /**
+ * Checks if the database server has started or not.
+ *
+ * @return True if started, false otherwise.
+ */
+ private boolean isStarted() {
+ try {
+ getControl().ping();
+
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets the controller for the database server.
+ *
+ * @return Controller.
+ * @throws Exception
+ */
+ private NetworkServerControl getControl() throws Exception {
+ return new NetworkServerControl();
+ }
+
+ /**
+ * Runs the database.
+ *
+ */
+ private void runDatabase() {
+ try {
+ getControl().start(new PrintWriter(System.out));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#getJdbcUrl()
+ */
+ public String getJdbcUrl() {
+ return getBaseJdbcUrl() +
+ ";create=true;retrieveMessagesFromServerOnGetMessage=true;";
+ }
+
+ private String getBaseJdbcUrl() {
+ return (inmemory ? "jdbc:derby:memory:" : "jdbc:derby:") +
+ DATABASE_NAME;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#getExternalJdbcUrl()
+ */
+ public String getExternalJdbcUrl() {
+ return "jdbc:derby://localhost:1527/" + (inmemory ? "memory:" : "") +
+ DATABASE_NAME;
+ }
+
+ /**
+ * Shuts down the derby database and cleans up all created files.
+ *
+ */
+ private void shutdownDerby() {
+ try {
+ DriverManager.getConnection("jdbc:derby:;shutdown=true");
+ throw new RuntimeException(
+ "Derby did not shutdown, should always throw exception at shutdown");
+ } catch (Exception e) {
+ LOGGER.info("Derby has been shut down.");
+ }
+ }
+
+ /**
+ * Gets the user name.
+ */
+ public String getUsername() {
+ return USERNAME;
+ }
+
+ /**
+ * Gets the password.
+ *
+ * @return
+ */
+ public String getPassword() {
+ return PASSWORD;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.wamblee.persistence.Database#createConnection()
+ */
+ public Connection createConnection() throws SQLException {
+ Connection c = DriverManager.getConnection(getJdbcUrl(), getUsername(),
+ getPassword());
+
+ return c;
+ }
+
+ /**
+ * Stops the derby database and cleans up all derby files.
+ */
+ public void doStop() {
+ try {
+ // shutdown network server.
+ getControl().shutdown();
+ waitUntilStartedOrStopped(false);
+
+ // shutdown inmemory access.
+ shutdownDerby();
+ cleanPersistentStorage();
+ } catch (Exception e) {
+ LOGGER.log(Level.WARNING, "Problem stopping database", e);
+ }
+ }
+
+ /**
+ * Cleans up persistent storage of Derby.
+ */
+ private void cleanPersistentStorage() {
+ File lFile = new File(DATABASE_PATH);
+
+ if (lFile.isFile()) {
+ TestCase.fail("A regular file by the name " + DATABASE_PATH +
+ " exists, clean this up first");
+ }
+
+ if (!lFile.isDirectory()) {
+ return; // no-op already cleanup up.
+ }
+ FileSystemUtils.deleteDirRecursively(DATABASE_PATH);
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.Arrays;
import java.util.List;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DerbyDatabaseProvider extends AbstractDatabaseProvider {
-
- /**
- * Capabilities of this type of database.
- */
- public static final List<String> CAPABILIITIES =
- Arrays.asList(DatabaseProvider.CAPABILITY_IN_MEMORY, "DERBY");
+ /**
+ * Capabilities of this type of database.
+ */
+ public static final List<String> CAPABILIITIES = Arrays.asList(
+ DatabaseProvider.CAPABILITY_IN_MEMORY, "DERBY");
+ /**
+ * Creates a new DerbyDatabaseProvider object.
+ */
+ public DerbyDatabaseProvider() {
+ // Empty
+ }
- public DerbyDatabaseProvider() {
- // Empty
- }
-
- public Database create() {
- return new DerbyDatabase();
- }
+ public Database create() {
+ return new DerbyDatabase();
+ }
- public DatabaseDescription getDescription() {
- return new DatabaseDescription(CAPABILIITIES.toArray(new String[0]),
- "Derby", "In-memory, volatile, set breakpoint to debug");
- }
+ public DatabaseDescription getDescription() {
+ return new DatabaseDescription(CAPABILIITIES.toArray(new String[0]),
+ "Derby", "In-memory, volatile, set breakpoint to debug");
+ }
@Override
protected List<String> getCapabilities() {
- return CAPABILIITIES;
+ return CAPABILIITIES;
}
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
-import java.util.Arrays;
-import java.util.List;
import java.util.logging.Logger;
import javax.sql.DataSource;
-import org.apache.commons.dbcp.ConnectionFactory;
-import org.apache.commons.dbcp.DriverManagerConnectionFactory;
-import org.apache.commons.dbcp.PoolableConnectionFactory;
-import org.apache.commons.dbcp.PoolingDataSource;
-import org.apache.commons.pool.impl.GenericObjectPool;
-
/**
- * Database that encapsulates connection to an external database.
- * Database connection details can be configured through system properties
- * and environment variables, see {@link #DB_URL_PROP}, {@link #DB_USER_PROP}, and
- * {@link #DB_PASSWORD_PROP|.
+ * Database that encapsulates connection to an external database. Database
+ * connection details can be configured through system properties and
+ * environment variables, see {@link #DB_URL_PROP}, {@link #DB_USER_PROP}, and
+ * {@link #DB_PASSWORD_PROP|.
*
- * This class assumes modern database drivers that work together with java.util.ServiceLoader
- * so that explicitly doing a Class.forName() is not necessary to load the database driver.
+ * This class assumes modern database drivers that work together with
+ * java.util.ServiceLoader so that explicitly doing a Class.forName() is not
+ * necessary to load the database driver.
*/
public class ExternalDatabase extends AbstractDatabase {
-
- private static final Logger LOGGER = Logger.getLogger(ExternalDatabase.class.getName());
-
- /**
- * System property/environment variable that defines the database URL.
- */
- public static final String DB_URL_PROP = "TEST_DB_URL";
-
- /**
- * System property/environment variable that defines the database user.
- */
- public static final String DB_USER_PROP = "TEST_DB_USER";
-
- /**
- * System property/environment variable that defines the database password.
- */
- public static final String DB_PASSWORD_PROP = "TEST_DB_PASSWORD";
-
-
- private String itsUrl;
- private String itsUser;
- private String itsPassword;
-
- private DataSource itsDataSource;
-
- public ExternalDatabase() {
- // Empty
- }
-
- public String getExternalJdbcUrl() {
- return itsUrl;
- }
-
- public String getJdbcUrl() {
- return itsUrl;
- }
-
- public String getPassword() {
- return itsPassword;
- }
-
- public String getUsername() {
- return itsUser;
- }
-
- public void doStart() {
- itsUrl = getProperty(DB_URL_PROP);
- itsUser = getProperty(DB_USER_PROP);
- itsPassword = getProperty(DB_PASSWORD_PROP);
-
- createDataSource();
- }
-
- public void doStop() {
- // Empty.
- }
+
+ private static final Logger LOGGER = Logger
+ .getLogger(ExternalDatabase.class.getName());
+
+ /**
+ * System property/environment variable that defines the database URL.
+ */
+ public static final String DB_URL_PROP = "TEST_DB_URL";
+
+ /**
+ * System property/environment variable that defines the database user.
+ */
+ public static final String DB_USER_PROP = "TEST_DB_USER";
+
+ /**
+ * System property/environment variable that defines the database password.
+ */
+ public static final String DB_PASSWORD_PROP = "TEST_DB_PASSWORD";
+
+ private String itsUrl;
+ private String itsUser;
+ private String itsPassword;
+
+ private DataSource itsDataSource;
+
+ public ExternalDatabase() {
+ // Empty
+ }
+
+ public String getExternalJdbcUrl() {
+ return itsUrl;
+ }
+
+ public String getJdbcUrl() {
+ return itsUrl;
+ }
+
+ public String getPassword() {
+ return itsPassword;
+ }
+
+ public String getUsername() {
+ return itsUser;
+ }
+
+ public void doStart() {
+ itsUrl = getProperty(DB_URL_PROP);
+ itsUser = getProperty(DB_USER_PROP);
+ itsPassword = getProperty(DB_PASSWORD_PROP);
+
+ createDataSource();
+ }
+
+ public void doStop() {
+ // Empty.
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.Arrays;
public class ExternalDatabaseProvider extends AbstractDatabaseProvider {
- /**
- * Capabilities of this type of database.
- */
- public static final List<String> CAPABILIITIES = Arrays
- .asList(CAPABILITY_EXTERNAL);
+ /**
+ * Capabilities of this type of database.
+ */
+ public static final List<String> CAPABILIITIES = Arrays
+ .asList(CAPABILITY_EXTERNAL);
- @Override
- protected List<String> getCapabilities() {
- return CAPABILIITIES;
- }
+ @Override
+ protected List<String> getCapabilities() {
+ return CAPABILIITIES;
+ }
- public Database create() {
- return new ExternalDatabase();
- }
+ public Database create() {
+ return new ExternalDatabase();
+ }
- public DatabaseDescription getDescription() {
- return new DatabaseDescription(
- CAPABILIITIES.toArray(new String[0]),
- "External Database",
- "Any database as described by the JDBC URL: requires system properties or environment variables: "
- + ExternalDatabase.DB_URL_PROP
- + ", "
- + ExternalDatabase.DB_USER_PROP
- + ", and "
- + ExternalDatabase.DB_PASSWORD_PROP);
- }
+ public DatabaseDescription getDescription() {
+ return new DatabaseDescription(
+ CAPABILIITIES.toArray(new String[0]),
+ "External Database",
+ "Any database as described by the JDBC URL: requires system properties or environment variables: " +
+ ExternalDatabase.DB_URL_PROP +
+ ", " +
+ ExternalDatabase.DB_USER_PROP +
+ ", and " +
+ ExternalDatabase.DB_PASSWORD_PROP);
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.Map;
import org.wamblee.support.jndi.StubInitialContextFactory;
-
/**
* Utility for building an appropriately configured EntityManagerFactory. The
* idea is that a persistence.xml is used unchanged from the production version.
*/
public class JpaBuilder {
- private static final Logger LOGGER = Logger.getLogger(JpaBuilder.class
- .getName());
+ private static final Logger LOGGER = Logger.getLogger(JpaBuilder.class
+ .getName());
+
+ /**
+ * Callback interface to execute some JPA code within a transaction with the
+ * entitymanager to use provided as input.
+ */
+ public static interface JpaUnitOfWork<T> {
+ /**
+ * Executes the unit of work. A transaction has been started.
+ *
+ * @param aEm
+ * Entity manager.
+ * @return Result of the execute method. If you don't want to return
+ * anything use <code>Void</code> for the return type and return
+ * null from the implementation.
+ */
+ T execute(EntityManager aEm) throws Exception;
+ }
+
+ private PersistenceUnitDescription persistenceUnit;
+ private DataSource dataSource;
+ private EntityManagerFactory factory;
+
+ /**
+ * Constructs the builder.
+ *
+ * @param aDataSource
+ * Datasource of database.
+ * @param aPersistenceUnit
+ * Persistence unit.
+ */
+ public JpaBuilder(DataSource aDataSource,
+ PersistenceUnitDescription aPersistenceUnit) {
+ persistenceUnit = aPersistenceUnit;
+ dataSource = aDataSource;
+ StubInitialContextFactory.register();
+ }
- /**
- * Callback interface to execute some JPA code within a transaction with the
- * entitymanager to use provided as input.
- */
- public static interface JpaUnitOfWork<T> {
- /**
- * Executes the unit of work. A transaction has been started.
- * @param em Entity manager.
- * @return Result of the execute method. If you don't want to return anything use
- * <code>Void</code> for the return type and return null from the implementation.
- */
- T execute(EntityManager em);
- }
+ /**
+ * Starts the builder, which in particular, mocks JNDI, binds the datasource
+ * the JNDI where the persistence unit expects it, creates the entity
+ * manager factory, and forces creation of the database schema.
+ */
+ public void start() throws Exception {
+ try {
+ InitialContext ctx = new InitialContext();
+ ctx.bind(persistenceUnit.getJndiName(), dataSource);
+ } catch (NamingException e) {
+ throw new RuntimeException("JNDI problem", e);
+ }
+ factory = createFactory();
+ execute(new JpaUnitOfWork<Void>() {
+ public Void execute(EntityManager aEm) {
+ // Empty, just to trigger database schema creation.
+ return null;
+ }
+ });
+ }
- private PersistenceUnitDescription persistenceUnit;
- private DataSource dataSource;
- private EntityManagerFactory factory;
+ /**
+ * Stops the entity manager factory and disables JNDI mocking.
+ */
+ public void stop() {
+ StubInitialContextFactory.unregister();
+ factory.close();
+ }
- /**
- * Constructs the builder.
- *
- * @param aDataSource
- * Datasource of database.
- * @param aPersistenceUnit
- * Persistence unit.
- */
- public JpaBuilder(DataSource aDataSource,
- PersistenceUnitDescription aPersistenceUnit) {
- persistenceUnit = aPersistenceUnit;
- dataSource = aDataSource;
- StubInitialContextFactory.register();
- }
+ /**
+ * Creates a new entity manager factory. Typically not used by test code.
+ *
+ * @return Entity manager factory.
+ */
+ public EntityManagerFactory createFactory() {
+ Map<String, String> jpaProps = new TreeMap<String, String>();
- /**
- * Starts the builder, which in particular, mocks JNDI, binds the datasource
- * the JNDI where the persistence unit expects it, creates the entity
- * manager factory, and forces creation of the database schema.
- */
- public void start() throws Exception {
- try {
- InitialContext ctx = new InitialContext();
- ctx.bind(persistenceUnit.getJndiName(), dataSource);
- } catch (NamingException e) {
- throw new RuntimeException("JNDI problem", e);
- }
- factory = createFactory();
- execute(new JpaUnitOfWork<Void>() {
- public Void execute(EntityManager em) {
- // Empty, just to trigger database schema creation.
- return null;
- }
- });
- }
+ JpaCustomizerBuilder.getCustomizer().customize(persistenceUnit,
+ jpaProps);
- /**
- * Stops the entity manager factory and disables JNDI mocking.
- */
- public void stop() {
- StubInitialContextFactory.unregister();
- factory.close();
- }
+ // jpaProps.put("javax.persistence.provider",
+ // HibernatePersistence.class.getName());
+ EntityManagerFactory factory = Persistence.createEntityManagerFactory(
+ persistenceUnit.getUnitName(), jpaProps);
- /**
- * Creates a new entity manager factory. Typically not used by test code.
- * @return Entity manager factory.
- */
- public EntityManagerFactory createFactory() {
- Map<String, String> jpaProps = new TreeMap<String, String>();
-
- JpaCustomizerBuilder.getCustomizer().customize(persistenceUnit, jpaProps);
-
- //jpaProps.put("javax.persistence.provider", HibernatePersistence.class.getName());
- EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenceUnit
- .getUnitName(), jpaProps);
-
- LOGGER.info("Using " + factory.getClass());
- return factory;
- }
+ LOGGER.info("Using " + factory.getClass());
+ return factory;
+ }
- /**
- * Executes a unit of work. This creates an entitymanager and runs the
- * {@link JpaUnitOfWork#execute(EntityManager)} within a transaction, passing
- * it the entity manager. Use of this method saves a lot of typing for applications.
- *
- * @param aWork Work to execute.
- * @return The return value of the execute method of the unit of work.
- */
- public <T> T execute(JpaUnitOfWork<T> aWork) throws Exception {
- EntityManager em = factory.createEntityManager();
- EntityTransaction transaction = em.getTransaction();
- transaction.begin();
- try {
- T value = aWork.execute(em);
- transaction.commit();
- return value;
- } catch (Exception e) {
- LOGGER.log(Level.WARNING, "Exception occured", e);
- transaction.rollback();
- throw e;
- } finally {
- em.close();
- }
- }
+ /**
+ * Executes a unit of work. This creates an entitymanager and runs the
+ * {@link JpaUnitOfWork#execute(EntityManager)} within a transaction,
+ * passing it the entity manager. Use of this method saves a lot of typing
+ * for applications.
+ *
+ * @param aWork
+ * Work to execute.
+ * @return The return value of the execute method of the unit of work.
+ */
+ public <T> T execute(JpaUnitOfWork<T> aWork) throws Exception {
+ EntityManager em = factory.createEntityManager();
+ EntityTransaction transaction = em.getTransaction();
+ transaction.begin();
+ try {
+ T value = aWork.execute(em);
+ transaction.commit();
+ return value;
+ } catch (Exception e) {
+ LOGGER.log(Level.WARNING, "Exception occured", e);
+ transaction.rollback();
+ throw e;
+ } finally {
+ em.close();
+ }
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.Map;
import org.dbunit.dataset.filter.ITableFilterSimple;
/**
- * JPA customizer is used to customize properties for a given JPA implementation.
+ * JPA customizer is used to customize properties for a given JPA
+ * implementation.
*
- * Implementations of JpaCustomizer are found using {@link ServiceLoader}. In case
- * of testing with a specific JPA provider, the customizer library for that JPA provider
- * must be on the classpath as well.
+ * Implementations of JpaCustomizer are found using {@link ServiceLoader}. In
+ * case of testing with a specific JPA provider, the customizer library for that
+ * JPA provider must be on the classpath as well.
*
* @author Erik Brakkee
*/
public interface JpaCustomizer {
- void customize(PersistenceUnitDescription aPersistenceUnit, Map<String,String> aJpaProperties);
-
+ void customize(PersistenceUnitDescription aPersistenceUnit,
+ Map<String, String> aJpaProperties);
+
ITableFilterSimple getJpaTables();
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.util.ArrayList;
public class JpaCustomizerBuilder {
- private static final ServiceLoader<JpaCustomizer> CUSTOMIZERS =
- ServiceLoader.load(JpaCustomizer.class);
-
-
- public static JpaCustomizer getCustomizer() {
- List<JpaCustomizer> customizers = new ArrayList<JpaCustomizer>();
- for (JpaCustomizer customizer: CUSTOMIZERS) {
+ private static final ServiceLoader<JpaCustomizer> CUSTOMIZERS = ServiceLoader
+ .load(JpaCustomizer.class);
+
+ public static JpaCustomizer getCustomizer() {
+ List<JpaCustomizer> customizers = new ArrayList<JpaCustomizer>();
+ for (JpaCustomizer customizer : CUSTOMIZERS) {
customizers.add(customizer);
}
return new CompositeJpaCustomizer(customizers);
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import javax.sql.DataSource;
import org.dbunit.IDatabaseTester;
/**
- * This class is the entry point for JPA tests. Test code should construct a JpaTester in the
- * <code>@Before</code> method and call {@link #start()} on it in that method. Also, test code should
- * call {@link #stop()} on it in the <code>@After</code> method.
+ * This class is the entry point for JPA tests. Test code should construct a
+ * JpaTester in the <code>@Before</code> method and call {@link #start()} on it
+ * in that method. Also, test code should call {@link #stop()} on it in the
+ * <code>@After</code> method.
+ *
+ * This class is constructed with a description of the persistence unit to be
+ * tested. The principle is that an existing <code>persistence.xml</code> can be
+ * tested without change in unit test code.
*
- * This class is constructed with a description of the persistence unit to be tested. The principle is that
- * an existing <code>persistence.xml</code> can be tested without change in unit test code.
- *
- * It then takes care of the following:
- * <ul>
- * <li> Creating an inmemory database for testing (default) or connecting to an external database.
- * See {@link DatabaseBuilder} for more information on how a databse is obtained.
- * </li>
- * <li> Drop all database tables that are related to the persistence unit under test, including JPA provider
- * specific tables.
- * </li>
- * <li> Creating a datasource for the database and make the datasource available through JNDI.
- * </li>
- * <li> Creating the entity manager factory for JPA and configuring it in such a way that schema creation
- * happens. (Typically, schema creation will be disabled in the persistence.xml but this utility enables it
- * for unit test).
- * </li>
- * <li> Creating a DBUnit database tester which is appropriately configured for the persistence unit under test.
- * </li>
+ * It then takes care of the following:
+ * <ul>
+ * <li>Creating an inmemory database for testing (default) or connecting to an
+ * external database. See {@link DatabaseBuilder} for more information on how a
+ * databse is obtained.</li>
+ * <li>Drop all database tables that are related to the persistence unit under
+ * test, including JPA provider specific tables.</li>
+ * <li>Creating a datasource for the database and make the datasource available
+ * through JNDI.</li>
+ * <li>Creating the entity manager factory for JPA and configuring it in such a
+ * way that schema creation happens. (Typically, schema creation will be
+ * disabled in the persistence.xml but this utility enables it for unit test).</li>
+ * <li>Creating a DBUnit database tester which is appropriately configured for
+ * the persistence unit under test.</li>
* </ul>
*
- * The main entry point for all this functionality is the {@link PersistenceUnitDescription} which describes the
- * persistence unit and must be provided at construction of the <code>JpaTester</code>
+ * The main entry point for all this functionality is the
+ * {@link PersistenceUnitDescription} which describes the persistence unit and
+ * must be provided at construction of the <code>JpaTester</code>
*
- * NOTE: Persistence XML files should be explicitly configured with the classes that are part of the persistence unit
- * since scanning of classes does not work correctly in a unit test environment. This is currently the only limitation.
+ * NOTE: Persistence XML files should be explicitly configured with the classes
+ * that are part of the persistence unit since scanning of classes does not work
+ * correctly in a unit test environment. This is currently the only limitation.
*/
public class JpaTester {
- private PersistenceUnitDescription persistenceUnit;
- private Database db;
- private DataSource dataSource;
- private DatabaseUtils dbUtils;
- private JpaBuilder jpaBuilder;
- private IDatabaseTester dbTester;
-
- /**
- * Constructs the tester.
- * @param aPersistenceUnit Persistence unit under test.
- */
- public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
- persistenceUnit = aPersistenceUnit;
- }
-
- /**
- * Starts the tester. This must be called prior to running the test.
- * @throws Exception
- */
- public void start() throws Exception {
- db = DatabaseBuilder.getDatabase();
- dataSource = db.start();
-
- dbUtils = new DatabaseUtils(dataSource, persistenceUnit.getTables());
- dbUtils.dropTables();
- dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
-
- jpaBuilder = new JpaBuilder(dataSource, persistenceUnit);
- jpaBuilder.start();
-
- // db tester should be created after Jpa builder because jpa builder
- // creates the
- // tables that the tester looks at when it is initialized.
- dbTester = dbUtils.createDbTester();
- }
-
- /**
- * Stops the tester. This must be called after the test.
- */
- public void stop() {
- if (jpaBuilder != null) {
- jpaBuilder.stop();
- }
- if (db != null) {
- db.stop();
- }
- }
-
- public Database getDb() {
- return db;
- }
-
- public DataSource getDataSource() {
- return dataSource;
- }
-
- public IDatabaseTester getDbTester() {
- return dbTester;
- }
-
- public DatabaseUtils getDbUtils() {
- return dbUtils;
- }
-
- public JpaBuilder getJpaBuilder() {
- return jpaBuilder;
- }
-
- public PersistenceUnitDescription getPersistenceUnit() {
- return persistenceUnit;
- }
+ private PersistenceUnitDescription persistenceUnit;
+ private Database db;
+ private DataSource dataSource;
+ private DatabaseUtils dbUtils;
+ private JpaBuilder jpaBuilder;
+ private IDatabaseTester dbTester;
+
+ /**
+ * Constructs the tester.
+ *
+ * @param aPersistenceUnit
+ * Persistence unit under test.
+ */
+ public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
+ persistenceUnit = aPersistenceUnit;
+ }
+
+ /**
+ * Starts the tester. This must be called prior to running the test.
+ *
+ * @throws Exception
+ */
+ public void start() throws Exception {
+ db = DatabaseBuilder.getDatabase();
+ dataSource = db.start();
+
+ dbUtils = new DatabaseUtils(dataSource, persistenceUnit.getTables());
+ dbUtils.dropTables();
+ dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
+
+ jpaBuilder = new JpaBuilder(dataSource, persistenceUnit);
+ jpaBuilder.start();
+
+ // db tester should be created after Jpa builder because jpa builder
+ // creates the
+ // tables that the tester looks at when it is initialized.
+ dbTester = dbUtils.createDbTester();
+ }
+
+ /**
+ * Stops the tester. This must be called after the test.
+ */
+ public void stop() {
+ if (jpaBuilder != null) {
+ jpaBuilder.stop();
+ }
+ if (db != null) {
+ db.stop();
+ }
+ }
+
+ public Database getDb() {
+ return db;
+ }
+
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ public IDatabaseTester getDbTester() {
+ return dbTester;
+ }
+
+ public DatabaseUtils getDbUtils() {
+ return dbUtils;
+ }
+
+ public JpaBuilder getJpaBuilder() {
+ return jpaBuilder;
+ }
+
+ public PersistenceUnitDescription getPersistenceUnit() {
+ return persistenceUnit;
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import org.dbunit.dataset.filter.ITableFilterSimple;
public class PersistenceUnitDescription {
- private String jndiName;
- private String unitName;
- private ITableFilterSimple tables;
-
- public PersistenceUnitDescription(String aJndiName, String aUnitName, ITableFilterSimple aTables) {
- jndiName = aJndiName;
- unitName = aUnitName;
- tables = aTables;
- }
-
- public String getJndiName() {
- return jndiName;
- }
-
- public String getUnitName() {
- return unitName;
- }
-
- public ITableFilterSimple getTables() {
- return tables;
- }
+ private String jndiName;
+ private String unitName;
+ private ITableFilterSimple tables;
+
+ public PersistenceUnitDescription(String aJndiName, String aUnitName,
+ ITableFilterSimple aTables) {
+ jndiName = aJndiName;
+ unitName = aUnitName;
+ tables = aTables;
+ }
+
+ public String getJndiName() {
+ return jndiName;
+ }
+
+ public String getUnitName() {
+ return unitName;
+ }
+
+ public ITableFilterSimple getTables() {
+ return tables;
+ }
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+import javax.persistence.EntityManager;
+
+import org.wamblee.support.ThreadSpecificProxyFactory;
+import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
+
+/**
+ * This utility makes sure that each invocation on a certain interface is
+ * carried out within a JPA unit of work.
+ *
+ * Use {@link #getTransactionScopedEntityManager()} to get the transaction
+ * scoped entity manager to pass to services.
+ *
+ * @param T
+ * Type of interface to proxy.
+ *
+ * @author Erik Brakkee
+ */
+public class TransactionProxyFactory<T> {
+
+ private class UnitOfWorkInvocationHandler<T> implements InvocationHandler {
+
+ private T service;
+
+ public UnitOfWorkInvocationHandler(T aService) {
+ service = aService;
+ }
+
+ @Override
+ public Object invoke(Object aProxy, final Method aMethod,
+ final Object[] aArgs) throws Throwable {
+ return TransactionProxyFactory.this.jpaBuilder
+ .execute(new JpaUnitOfWork<Object>() {
+ @Override
+ public Object execute(EntityManager aEm) throws Exception {
+ try {
+ ENTITY_MANAGER.set(aEm);
+ return aMethod.invoke(service, aArgs);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof Exception) {
+ throw (Exception) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ }
+ // last resort.
+ throw new RuntimeException(e);
+ } finally {
+ ENTITY_MANAGER.set(null);
+ }
+ }
+ });
+ }
+
+ }
+
+ private static final ThreadSpecificProxyFactory<EntityManager> ENTITY_MANAGER = new ThreadSpecificProxyFactory<EntityManager>(
+ EntityManager.class);
+
+ private JpaBuilder jpaBuilder;
+ private Class<T> clazz;
+
+ /**
+ * Constructs the transaction proxy.
+ *
+ * @param aJpaBuilder
+ */
+ public TransactionProxyFactory(JpaBuilder aJpaBuilder, Class<T> aClass) {
+ jpaBuilder = aJpaBuilder;
+ clazz = aClass;
+ }
+
+ public EntityManager getTransactionScopedEntityManager() {
+ return ENTITY_MANAGER.getProxy();
+ }
+
+ public T getProxy(T aService) {
+ InvocationHandler handler = new UnitOfWorkInvocationHandler<T>(aService);
+ Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(),
+ new Class[] { clazz });
+ T proxy;
+ try {
+ proxy = (T) proxyClass.getConstructor(
+ new Class[] { InvocationHandler.class }).newInstance(
+ new Object[] { handler });
+ return proxy;
+ } catch (Exception e) {
+ throw new RuntimeException("Could not create proxy for " +
+ clazz.getName(), e);
+ }
+ }
+}
-/**
- * This package provide a number of utilities for database testing and in particular with
- * JPA.
+/*
+ * Copyright 2005-2010 the original author or authors.
*
- * The following utilities are available:
- * <ul>
- * <li> {@link JpaTester}: The main entry point for all JPA tests.
- * </li>
- * <li> {@link JpaBuilder}: A utility constructed by <code>JpaTester</code> that provides a callback based
- * style of working with transaction-scoped entity managers.
- * </li>
- * <li> {@link DatabaseUtils}: A utility constructed by <code>JpaTester</code> for working with databases in general. Test code will not use this
- * utility often.
- * </li>
- * <li> {@link org.dbunit.IDatabaseTester}: A DB unit database tester. The test code can use this database tester.
- * It is also created by <code>JpaTester</code>
- * </li>
- * <li> {@link DatabaseBuilder}: A utility by which test code can transparently create an inmemory database or
- * connect to an external database. This is also used by <code>JpaTester</code>
- * </li>
- * </ul>
- */
+ * Licensed 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.wamblee.support.persistence;
+
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support;
+
+import static junit.framework.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ThreadSpecificProxyFactoryTest {
+
+ private static interface Service {
+ int execute(int aX) throws Exception;
+ }
+
+ private ThreadSpecificProxyFactory<Service> factory;
+ private Service proxy;
+
+ @Before
+ public void setUp() {
+ factory = new ThreadSpecificProxyFactory<Service>(Service.class);
+ proxy = factory.getProxy();
+ }
+
+ @After
+ public void tearDown() {
+ // Empty.
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNoSvcDefined() throws Exception {
+ proxy.execute(10);
+ }
+
+ @Test
+ public void testInvokeThroughProxy() throws Exception {
+ Service svc = mock(Service.class);
+ when(svc.execute(anyInt())).thenReturn(50);
+ factory.set(svc);
+ assertEquals(50, proxy.execute(10));
+ verify(svc).execute(10);
+ }
+
+ @Test
+ public void testInvokeThroughProxyWithException() throws Exception {
+ Service svc = mock(Service.class);
+ try {
+ when(svc.execute(anyInt())).thenThrow(
+ new RuntimeException("exception thrown"));
+ factory.set(svc);
+ svc.execute(10);
+ fail();
+ } catch (RuntimeException e) {
+ assertEquals("exception thrown", e.getMessage());
+ }
+ }
+
+ private int returnFromThread;
+
+ @Test
+ public void testVerifyThreadSpecificUsingTwoThreads() throws Exception {
+ Service svc1 = mock(Service.class);
+ final Service svc2 = mock(Service.class);
+ when(svc1.execute(anyInt())).thenReturn(10);
+ when(svc2.execute(anyInt())).thenReturn(20);
+
+ factory.set(svc1);
+ assertEquals(10, svc1.execute(10));
+ Thread t = new Thread() {
+ public void run() {
+ factory.set(svc2);
+ try {
+ returnFromThread = proxy.execute(100);
+ } catch (Exception e) {
+ returnFromThread = 100000;
+ }
+ };
+ };
+ t.start();
+ t.join();
+ assertEquals(20, returnFromThread);
+ assertEquals(10, proxy.execute(100));
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNotAnInterface() {
+ ThreadSpecificProxyFactory f = new ThreadSpecificProxyFactory(String.class);
+ }
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.jndi;
import static junit.framework.Assert.assertEquals;
public class StubInitiaContextFactoryTest {
- @Before
- @After
- public void setUp() {
- StubInitialContextFactory.unregister();
- }
-
-
- @Test(expected = NamingException.class)
- public void testLookupNotRegistered() throws Exception {
- InitialContext ctx = new InitialContext();
- ctx.bind("a/b", "hallo");
- }
-
- @Test
- public void testLookup() throws Exception {
- StubInitialContextFactory.register();
-
- InitialContext ctx = new InitialContext();
- ctx.bind("a/b", "hallo");
-
- ctx = new InitialContext();
- Object obj = ctx.lookup("a/b");
-
- assertEquals("hallo", obj);
- }
-
+ @Before
+ @After
+ public void setUp() {
+ StubInitialContextFactory.unregister();
+ }
+
+ @Test(expected = NamingException.class)
+ public void testLookupNotRegistered() throws Exception {
+ InitialContext ctx = new InitialContext();
+ ctx.bind("a/b", "hallo");
+ }
+
+ @Test
+ public void testLookup() throws Exception {
+ StubInitialContextFactory.register();
+
+ InitialContext ctx = new InitialContext();
+ ctx.bind("a/b", "hallo");
+
+ ctx = new InitialContext();
+ Object obj = ctx.lookup("a/b");
+
+ assertEquals("hallo", obj);
+ }
+
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import org.junit.Test;
public class DatabaseBuilderTest {
-
- @Test
- public void testListAvailableDatabases() {
- for (DatabaseDescription description: DatabaseBuilder.getSupportedDatabases()) {
- System.out.println(description);
- }
- }
+ @Test
+ public void testListAvailableDatabases() {
+ for (DatabaseDescription description : DatabaseBuilder
+ .getSupportedDatabases()) {
+ System.out.println(description);
+ }
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import static junit.framework.Assert.assertEquals;
builder = new JpaBuilder(dataSource, persistenceUnit);
builder.start();
-
+
dbtester = dbutils.createDbTester();
}
// Put some data in the database.
builder.execute(new JpaUnitOfWork<Void>() {
- public Void execute(EntityManager em) {
+ public Void execute(EntityManager aEm) {
MyEntity entity = new MyEntity("a", "b");
- em.persist(entity);
+ aEm.persist(entity);
return null;
}
});
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.sql.Connection;
import org.wamblee.support.persistence.Database;
import org.wamblee.support.persistence.DatabaseBuilder;
-
public class DerbyDatabaseTest {
- private Database db;
- private DataSource ds;
-
- @Before
- public void setUp() {
- db = DatabaseBuilder.getDatabase();
- ds = db.start();
- }
-
- @After
- public void tearDown() {
- db.stop();
- }
-
- @Test
- public void testConnect() throws Exception {
- Connection conn = ds.getConnection();
- try {
- System.out.println("Database name: " + conn.getMetaData().getDatabaseProductName());
- } finally {
- conn.close();
- }
- }
-
- @Test
- public void testUseASecondTimeInTheSameTestCase() throws Exception {
- testConnect();
- tearDown();
- setUp();
- testConnect();
- }
+ private Database db;
+ private DataSource ds;
+
+ @Before
+ public void setUp() {
+ db = DatabaseBuilder.getDatabase();
+ ds = db.start();
+ }
+
+ @After
+ public void tearDown() {
+ db.stop();
+ }
+
+ @Test
+ public void testConnect() throws Exception {
+ Connection conn = ds.getConnection();
+ try {
+ System.out.println("Database name: " +
+ conn.getMetaData().getDatabaseProductName());
+ } finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testUseASecondTimeInTheSameTestCase() throws Exception {
+ testConnect();
+ tearDown();
+ setUp();
+ testConnect();
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import java.sql.Connection;
public class ExternalDatabaseTest {
- @Test
- public void testExternalDB() throws Exception {
- // Connect to inmemory db using External database class.
-
- Database inmemory = DatabaseBuilder
- .getDatabase(DatabaseProvider.CAPABILITY_IN_MEMORY);
- try {
- inmemory.start();
-
- System.setProperty(ExternalDatabase.DB_URL_PROP, inmemory
- .getExternalJdbcUrl());
- System.setProperty(ExternalDatabase.DB_USER_PROP, inmemory
- .getUsername());
- System.setProperty(ExternalDatabase.DB_PASSWORD_PROP, inmemory
- .getPassword());
-
- Database external = DatabaseBuilder
- .getDatabase(DatabaseProvider.CAPABILITY_EXTERNAL);
- assertTrue(external instanceof ExternalDatabase);
- try {
- DataSource ds = external.start();
- Connection conn = ds.getConnection();
- try {
- System.out.println("Database name: "
- + conn.getMetaData().getDatabaseProductName());
- } finally {
- conn.close();
- }
- } finally {
- external.stop();
- }
- } finally {
- inmemory.stop();
- }
-
- }
+ @Test
+ public void testExternalDB() throws Exception {
+ // Connect to inmemory db using External database class.
+
+ Database inmemory = DatabaseBuilder
+ .getDatabase(DatabaseProvider.CAPABILITY_IN_MEMORY);
+ try {
+ inmemory.start();
+
+ System.setProperty(ExternalDatabase.DB_URL_PROP, inmemory
+ .getExternalJdbcUrl());
+ System.setProperty(ExternalDatabase.DB_USER_PROP, inmemory
+ .getUsername());
+ System.setProperty(ExternalDatabase.DB_PASSWORD_PROP, inmemory
+ .getPassword());
+
+ Database external = DatabaseBuilder
+ .getDatabase(DatabaseProvider.CAPABILITY_EXTERNAL);
+ assertTrue(external instanceof ExternalDatabase);
+ try {
+ DataSource ds = external.start();
+ Connection conn = ds.getConnection();
+ try {
+ System.out.println("Database name: " +
+ conn.getMetaData().getDatabaseProductName());
+ } finally {
+ conn.close();
+ }
+ } finally {
+ external.stop();
+ }
+ } finally {
+ inmemory.stop();
+ }
+
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import javax.persistence.Entity;
@Table(name = "XYZ_MYENTITY")
public class MyEntity {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Long id;
-
- private String sleuteltje;
- private String value;
-
-
- public MyEntity() {
- // Empty
- }
-
- public MyEntity(String aKey, String aValue) {
- sleuteltje = aKey;
- value = aValue;
- }
-
- public String getKey() {
- return sleuteltje;
- }
-
- public String getValue() {
- return value;
- }
-
-
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ private String sleuteltje;
+ private String value;
+
+ public MyEntity() {
+ // Empty
+ }
+
+ public MyEntity(String aKey, String aValue) {
+ sleuteltje = aKey;
+ value = aValue;
+ }
+
+ public String getKey() {
+ return sleuteltje;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
+import static junit.framework.Assert.*;
+
import javax.persistence.EntityManager;
-import javax.persistence.Persistence;
-import javax.sql.DataSource;
-import org.dbunit.DataSourceDatabaseTester;
-import org.dbunit.DatabaseTestCase;
import org.dbunit.IDatabaseTester;
import org.dbunit.dataset.ITable;
-import org.dbunit.dataset.filter.ITableFilterSimple;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.wamblee.support.persistence.DatabaseUtils;
-import org.wamblee.support.persistence.JpaBuilder;
-import org.wamblee.support.persistence.JpaTester;
import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
-import static junit.framework.Assert.*;
-
-
/**
- * This class shows an example of how to test an entity using jpa.
+ * This class shows an example of how to test an entity using jpa.
*/
public class MyEntityExampleTestBase {
- // This is the magical object that does all the test setup.
- private JpaTester jpaTester;
-
+ // This is the magical object that does all the test setup.
+ private JpaTester jpaTester;
+
// The jpa tester initializes a lot for us....
-
- // A JPA builder that provides a transaction scoped entity manager for us.
- private JpaBuilder builder;
-
- // The database tester for dbunit which is appropriately configured for our persistence unit.
- private IDatabaseTester dbtester;
-
- // Database utilities with some additional functionality for working with the databse
- // such as dropping tables, cleaning tables, etc.
- private DatabaseUtils dbutils;
-
- @Before
- public void setUp() throws Exception {
-
- // First we create the JpaTester by telling us which persistence unit we are going to test
- jpaTester = new JpaTester(new MyPersistenceUnit());
- jpaTester.start();
-
- // Retrieve some useful objects fromt he jpa tester. It also provides direct access to the datasource
- // but we don't need it. We can use datbase utils if we want to execute straight JDBC calls.
- builder = jpaTester.getJpaBuilder();
- dbtester = jpaTester.getDbTester();
- dbutils = jpaTester.getDbUtils();
- }
-
- @After
- public void tearDown() {
- jpaTester.stop();
- }
-
- @Test
- public void testEntityPersistence() throws Exception {
-
- // Use the JPA builder to create a transaction scoped entity manager for as and execute the
- // unit of work.
- builder.execute(new JpaUnitOfWork<Void>() {
- public Void execute(EntityManager em) {
- MyEntity entity = new MyEntity("a", "b");
- em.persist(entity);
- return null;
- }
- });
-
- // Verify one row is written (using Db unit)
- ITable table = dbtester.getDataSet().getTable("XYZ_MYENTITY");
- assertEquals(1, table.getRowCount());
-
- assertEquals("a", table.getValue(0, "SLEUTELTJE"));
- assertEquals("b", table.getValue(0, "VALUE"));
-
- // For this simple test, it can also be done through DatabaseUtils
- assertEquals(1, dbutils.getTableSize("XYZ_MYENTITY"));
-
- }
+
+ // A JPA builder that provides a transaction scoped entity manager for us.
+ private JpaBuilder builder;
+
+ // The database tester for dbunit which is appropriately configured for our
+ // persistence unit.
+ private IDatabaseTester dbtester;
+
+ // Database utilities with some additional functionality for working with
+ // the databse
+ // such as dropping tables, cleaning tables, etc.
+ private DatabaseUtils dbutils;
+
+ @Before
+ public void setUp() throws Exception {
+
+ // First we create the JpaTester by telling us which persistence unit we
+ // are going to test
+ jpaTester = new JpaTester(new MyPersistenceUnit());
+ jpaTester.start();
+
+ // Retrieve some useful objects fromt he jpa tester. It also provides
+ // direct access to the datasource
+ // but we don't need it. We can use datbase utils if we want to execute
+ // straight JDBC calls.
+ builder = jpaTester.getJpaBuilder();
+ dbtester = jpaTester.getDbTester();
+ dbutils = jpaTester.getDbUtils();
+ }
+
+ @After
+ public void tearDown() {
+ jpaTester.stop();
+ }
+
+ @Test
+ public void testEntityPersistence() throws Exception {
+
+ // Use the JPA builder to create a transaction scoped entity manager for
+ // as and execute the
+ // unit of work.
+ builder.execute(new JpaUnitOfWork<Void>() {
+ public Void execute(EntityManager aEm) {
+ MyEntity entity = new MyEntity("a", "b");
+ aEm.persist(entity);
+ return null;
+ }
+ });
+
+ // Verify one row is written (using Db unit)
+ ITable table = dbtester.getDataSet().getTable("XYZ_MYENTITY");
+ assertEquals(1, table.getRowCount());
+
+ assertEquals("a", table.getValue(0, "SLEUTELTJE"));
+ assertEquals("b", table.getValue(0, "VALUE"));
+
+ // For this simple test, it can also be done through DatabaseUtils
+ assertEquals(1, dbutils.getTableSize("XYZ_MYENTITY"));
+
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import org.wamblee.support.persistence.PersistenceUnitDescription;
/**
- * This class describes the persistence unit that we are testing.
+ * This class describes the persistence unit that we are testing.
*/
public class MyPersistenceUnit extends PersistenceUnitDescription {
- private static final String JNDI_NAME = "wamblee/support/test";
- private static final String PERSISTENCE_UNIT_NAME = "org.wamblee.jee.support-test";
-
- public MyPersistenceUnit() {
- super(JNDI_NAME, PERSISTENCE_UNIT_NAME, new MyTables());
- }
+ private static final String JNDI_NAME = "wamblee/support/test";
+ private static final String PERSISTENCE_UNIT_NAME = "org.wamblee.jee.support-test";
+
+ public MyPersistenceUnit() {
+ super(JNDI_NAME, PERSISTENCE_UNIT_NAME, new MyTables());
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.filter.ITableFilterSimple;
/**
- * This class describes the tables we are testing.
- * This implementation selects all tables with the "XYZ" prefix.
+ * This class describes the tables we are testing. This implementation selects
+ * all tables with the "XYZ" prefix.
*/
public class MyTables implements ITableFilterSimple {
-
- /**
- *
- * @param aJpaTables Specific tables used by the JPA provider in addition to those for the
- * entities.
- */
- public MyTables() {
- // Empty.
- }
- public boolean accept(String tableName) throws DataSetException {
- return tableName.startsWith("XYZ_");
- }
+ /**
+ *
+ * @param aJpaTables
+ * Specific tables used by the JPA provider in addition to those
+ * for the entities.
+ */
+ public MyTables() {
+ // Empty.
+ }
+
+ public boolean accept(String aTableName) throws DataSetException {
+ return aTableName.startsWith("XYZ_");
+ }
}
--- /dev/null
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence;
+
+import javax.persistence.EntityManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
+
+import static junit.framework.TestCase.*;
+import static org.mockito.Mockito.*;
+
+public class TransactionProxyFactoryTestBase {
+
+ public static interface Service {
+ int execute(int aValue) throws Exception;
+ }
+
+ private JpaTester jpaTester;
+
+ @Before
+ public void setUp() throws Exception {
+ jpaTester = new JpaTester(new MyPersistenceUnit());
+ jpaTester.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ jpaTester.stop();
+ }
+
+ @Test
+ public void testServiceIsInvoked() throws Exception {
+ TransactionProxyFactory<Service> factory = new TransactionProxyFactory<Service>(
+ jpaTester.getJpaBuilder(), Service.class);
+ Service service = mock(Service.class);
+ when(service.execute(10)).thenReturn(200);
+ Service proxy = factory.getProxy(service);
+ int res = proxy.execute(10);
+ assertEquals(200, res);
+ verify(service).execute(10);
+ }
+
+ @Test
+ public void testServiceThrowsException() throws Exception {
+ TransactionProxyFactory<Service> factory = new TransactionProxyFactory<Service>(
+ jpaTester.getJpaBuilder(), Service.class);
+ Service service = mock(Service.class);
+ when(service.execute(10)).thenThrow(new RuntimeException("xyz"));
+ Service proxy = factory.getProxy(service);
+ try {
+ int res = proxy.execute(10);
+ fail();
+ } catch (RuntimeException e) {
+ assertEquals("xyz", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testEntityManagerIsPassed() throws Exception {
+
+
+ final TransactionProxyFactory<Service> factory = new TransactionProxyFactory<Service>(
+ jpaTester.getJpaBuilder(), Service.class);
+ Service service = new Service() {
+ private EntityManager em = factory.getTransactionScopedEntityManager();
+
+ @Override
+ public int execute(int aValue) throws Exception {
+ assertNotNull(em);
+ assertTrue(em.isOpen());
+ return 0;
+ }
+ };
+
+ final Service proxy = factory.getProxy(service);
+ jpaTester.getJpaBuilder().execute(new JpaUnitOfWork<Void>() {
+ @Override
+ public Void execute(EntityManager aEm) throws Exception {
+ assert(aEm != null);
+ proxy.execute(10);
+ return null;
+ }
+ });
+ }
+
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.hibernate;
-import java.util.Map;
-
import org.dbunit.dataset.filter.ITableFilterSimple;
+
import org.wamblee.support.persistence.JpaCustomizer;
import org.wamblee.support.persistence.PersistenceUnitDescription;
-public class HibernateJpaCustomizer implements JpaCustomizer {
+import java.util.Map;
- public HibernateJpaCustomizer() {
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class HibernateJpaCustomizer implements JpaCustomizer {
+ /**
+ * Creates a new HibernateJpaCustomizer object.
+ */
+ public HibernateJpaCustomizer() {
// Empty
}
-
+
@Override
- public void customize(PersistenceUnitDescription aPersistenceUnit, Map<String, String> aJpaProperties) {
+ public void customize(PersistenceUnitDescription aPersistenceUnit,
+ Map<String, String> aJpaProperties) {
// Hibernate: Override transaction type and datasource
- aJpaProperties.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
+ aJpaProperties.put("javax.persistence.transactionType",
+ "RESOURCE_LOCAL");
aJpaProperties.put("javax.persistence.jtaDataSource", null);
- aJpaProperties.put("javax.persistence.nonJtaDataSource", aPersistenceUnit.getJndiName());
-
+ aJpaProperties.put("javax.persistence.nonJtaDataSource",
+ aPersistenceUnit.getJndiName());
+
// Hibernate schema generation
- aJpaProperties.put("hibernate.hbm2ddl.auto", "create");
+ aJpaProperties.put("hibernate.hbm2ddl.auto", "create");
}
-
+
@Override
public ITableFilterSimple getJpaTables() {
return new HibernateTables();
}
-
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.hibernate;
-import java.util.Arrays;
-import java.util.List;
-
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.filter.ITableFilterSimple;
+import java.util.Arrays;
+import java.util.List;
+
/**
- * Toplink-specific tables.
+ * Toplink-specific tables.
*/
public class HibernateTables implements ITableFilterSimple {
+ private static final List<String> TABLES = Arrays
+ .asList(new String[] { "" });
- private static final List<String> TABLES = Arrays.asList(new String[] { "" } );
-
- public boolean accept(String aTableName) throws DataSetException {
- return TABLES.contains(aTableName);
- }
-
+ public boolean accept(String aTableName) throws DataSetException {
+ return TABLES.contains(aTableName);
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.hibernate;
-import static junit.framework.Assert.assertEquals;
-
-import javax.persistence.EntityManager;
-import javax.sql.DataSource;
-
-import org.dbunit.IDatabaseTester;
-import org.dbunit.dataset.ITable;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.wamblee.support.persistence.Database;
-import org.wamblee.support.persistence.DatabaseBuilder;
-import org.wamblee.support.persistence.DatabaseUtils;
import org.wamblee.support.persistence.DatabaseUtilsTestBase;
-import org.wamblee.support.persistence.JpaBuilder;
-import org.wamblee.support.persistence.PersistenceUnitDescription;
-import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DatabaseUtilsTest extends DatabaseUtilsTestBase {
- // Empty, all tests inherited
+ // Empty, all tests inherited
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.hibernate;
-import javax.persistence.EntityManager;
-import javax.persistence.Persistence;
-import javax.sql.DataSource;
-
-import org.dbunit.DataSourceDatabaseTester;
-import org.dbunit.DatabaseTestCase;
-import org.dbunit.IDatabaseTester;
-import org.dbunit.dataset.ITable;
-import org.dbunit.dataset.filter.ITableFilterSimple;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.wamblee.support.persistence.DatabaseUtils;
-import org.wamblee.support.persistence.JpaBuilder;
-import org.wamblee.support.persistence.JpaTester;
import org.wamblee.support.persistence.MyEntityExampleTestBase;
-import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
-
-import static junit.framework.Assert.*;
-
/**
- * This class shows an example of how to test an entity using jpa.
+ * This class shows an example of how to test an entity using jpa.
*/
public class MyEntityExampleTest extends MyEntityExampleTestBase {
// Empty, all tests are inherited
--- /dev/null
+package org.wamblee.support.persistence.hibernate;
+
+import org.wamblee.support.persistence.TransactionProxyFactoryTestBase;
+
+public class TransactionProxyFactoryTest extends
+ TransactionProxyFactoryTestBase {
+
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.toplink;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-
import oracle.toplink.essentials.jndi.JNDIConnector;
import oracle.toplink.essentials.sessions.DatabaseLogin;
import oracle.toplink.essentials.sessions.Session;
import oracle.toplink.essentials.threetier.ServerSession;
import oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer;
-
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
/**
- * See http://wiki.eclipse.org/Customizing_the_EclipseLink_Application_(ELUG) Use for clients that would like to use a
- * JTA SE pu instead of a RESOURCE_LOCAL SE pu.
- *
- * This utility also makes sure that using a persistence.xml with a JTA datasource works in a standalone Java SE
- * environment together with our JNDI stub.
+ * See http://wiki.eclipse.org/Customizing_the_EclipseLink_Application_(ELUG)
+ * Use for clients that would like to use a JTA SE pu instead of a
+ * RESOURCE_LOCAL SE pu. This utility also makes sure that using a
+ * persistence.xml with a JTA datasource works in a standalone Java SE
+ * environment together with our JNDI stub.
*/
-public class JndiSessionCustomizer
- implements SessionCustomizer {
-
- public JndiSessionCustomizer() {
- // Empty.
- }
-
- /**
- * Get a dataSource connection and set it on the session with lookupType=STRING_LOOKUP
- */
- public void customize(Session session) throws Exception {
- JNDIConnector connector = null;
- Context context = null;
- try {
- context = new InitialContext();
- if(null != context) {
- connector = (JNDIConnector)session.getLogin().getConnector(); // possible CCE
- // Change from COMPOSITE_NAME_LOOKUP to STRING_LOOKUP
- // Note: if both jta and non-jta elements exist this will only change the first one - and may still result in
- // the COMPOSITE_NAME_LOOKUP being set
- // Make sure only jta-data-source is in persistence.xml with no non-jta-data-source property set
- connector.setLookupType(JNDIConnector.STRING_LOOKUP);
-
- // Or, if you are specifying both JTA and non-JTA in your persistence.xml then set both connectors to be safe
- JNDIConnector writeConnector = (JNDIConnector)session.getLogin().getConnector();
- writeConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
- JNDIConnector readConnector =
- (JNDIConnector)((DatabaseLogin)((ServerSession)session).getReadConnectionPool().getLogin()).getConnector();
- readConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
-
- System.out.println("JndiSessionCustomizer: configured " + connector.getName());
- }
- else {
- throw new Exception("JndiSessionCustomizer: Context is null");
- }
+public class JndiSessionCustomizer implements SessionCustomizer {
+ /**
+ * Creates a new JndiSessionCustomizer object.
+ */
+ public JndiSessionCustomizer() {
+ // Empty.
}
- catch(Exception e) {
- e.printStackTrace();
+
+ /**
+ * Get a dataSource connection and set it on the session with
+ * lookupType=STRING_LOOKUP
+ *
+ *
+ */
+ public void customize(Session aSession) throws Exception {
+ JNDIConnector connector = null;
+ Context context = null;
+
+ try {
+ context = new InitialContext();
+
+ if (null != context) {
+ connector = (JNDIConnector) aSession.getLogin().getConnector(); // possible
+ // CCE
+ // Change from COMPOSITE_NAME_LOOKUP to STRING_LOOKUP
+ // Note: if both jta and non-jta elements exist this will only
+ // change the first one - and may still result in
+ // the COMPOSITE_NAME_LOOKUP being set
+ // Make sure only jta-data-source is in persistence.xml with no
+ // non-jta-data-source property set
+
+ connector.setLookupType(JNDIConnector.STRING_LOOKUP);
+
+ // Or, if you are specifying both JTA and non-JTA in your
+ // persistence.xml then set both connectors to be safe
+ JNDIConnector writeConnector = (JNDIConnector) aSession
+ .getLogin().getConnector();
+ writeConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
+
+ JNDIConnector readConnector = (JNDIConnector) ((DatabaseLogin) ((ServerSession) aSession)
+ .getReadConnectionPool().getLogin()).getConnector();
+ readConnector.setLookupType(JNDIConnector.STRING_LOOKUP);
+
+ System.out.println("JndiSessionCustomizer: configured " +
+ connector.getName());
+ } else {
+ throw new Exception("JndiSessionCustomizer: Context is null");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- }
-}
\ No newline at end of file
+}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.toplink;
-import java.util.Map;
-
import org.dbunit.dataset.filter.ITableFilterSimple;
+
import org.wamblee.support.persistence.JpaCustomizer;
import org.wamblee.support.persistence.PersistenceUnitDescription;
-public class ToplinkJpaCustomizer implements JpaCustomizer {
+import java.util.Map;
- public ToplinkJpaCustomizer() {
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
+public class ToplinkJpaCustomizer implements JpaCustomizer {
+ /**
+ * Creates a new ToplinkJpaCustomizer object.
+ */
+ public ToplinkJpaCustomizer() {
// Empty
}
-
+
@Override
- public void customize(PersistenceUnitDescription aPersistenceUnit, Map<String, String> aJpaProperties) {
+ public void customize(PersistenceUnitDescription aPersistenceUnit,
+ Map<String, String> aJpaProperties) {
// Hack to make JNDI lookup of the datasource work with toplink
- aJpaProperties.put("toplink.session.customizer", JndiSessionCustomizer.class
- .getName());
-
+ aJpaProperties.put("toplink.session.customizer",
+ JndiSessionCustomizer.class.getName());
+
// DDL generation for toplink
- aJpaProperties.put("toplink.ddl-generation", "create-tables");
+ aJpaProperties.put("toplink.ddl-generation", "create-tables");
}
-
+
@Override
public ITableFilterSimple getJpaTables() {
return new ToplinkTables();
}
-
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.toplink;
-import java.util.Arrays;
-import java.util.List;
-
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.filter.ITableFilterSimple;
+import java.util.Arrays;
+import java.util.List;
+
/**
- * Toplink-specific tables.
+ * Toplink-specific tables.
*/
public class ToplinkTables implements ITableFilterSimple {
+ private static final List<String> TABLES = Arrays
+ .asList(new String[] { "SEQUENCE" });
- private static final List<String> TABLES = Arrays.asList(new String[] { "SEQUENCE" } );
-
- public boolean accept(String aTableName) throws DataSetException {
- return TABLES.contains(aTableName);
- }
-
+ public boolean accept(String aTableName) throws DataSetException {
+ return TABLES.contains(aTableName);
+ }
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.toplink;
import static junit.framework.Assert.assertEquals;
-import javax.persistence.EntityManager;
-import javax.sql.DataSource;
-
import org.dbunit.IDatabaseTester;
+
import org.dbunit.dataset.ITable;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+
import org.wamblee.support.persistence.Database;
import org.wamblee.support.persistence.DatabaseBuilder;
import org.wamblee.support.persistence.DatabaseUtils;
import org.wamblee.support.persistence.DatabaseUtilsTestBase;
import org.wamblee.support.persistence.JpaBuilder;
-import org.wamblee.support.persistence.PersistenceUnitDescription;
import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
+import org.wamblee.support.persistence.PersistenceUnitDescription;
+
+import javax.persistence.EntityManager;
+
+import javax.sql.DataSource;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DatabaseUtilsTest extends DatabaseUtilsTestBase {
- // Empty, all tests inherited
+ // Empty, all tests inherited
}
+/*
+ * Copyright 2005-2010 the original author or authors.
+ *
+ * Licensed 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.wamblee.support.persistence.toplink;
-import javax.persistence.EntityManager;
-import javax.persistence.Persistence;
-import javax.sql.DataSource;
+import static junit.framework.Assert.*;
import org.dbunit.DataSourceDatabaseTester;
import org.dbunit.DatabaseTestCase;
import org.dbunit.IDatabaseTester;
+
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.filter.ITableFilterSimple;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+
import org.wamblee.support.persistence.DatabaseUtils;
import org.wamblee.support.persistence.JpaBuilder;
+import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
import org.wamblee.support.persistence.JpaTester;
import org.wamblee.support.persistence.MyEntityExampleTestBase;
-import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
-import static junit.framework.Assert.*;
+import javax.persistence.EntityManager;
+import javax.persistence.Persistence;
+import javax.sql.DataSource;
/**
- * This class shows an example of how to test an entity using jpa.
+ * This class shows an example of how to test an entity using jpa.
*/
public class MyEntityExampleTest extends MyEntityExampleTestBase {
// Empty, all tests are inherited