Updated Spring formatting conventions to disallow spaces as leading whitespace. Only tabs are allowed now. Some spelling updates as well.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#Tue Jul 31 15:11:23 EDT 2007
|
||||
#Mon Aug 13 12:00:34 EDT 2007
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.3
|
||||
@@ -142,7 +142,7 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.indentation.size=8
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
@@ -322,7 +322,7 @@ org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=mixed
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=8
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Tue Jul 31 15:11:23 EDT 2007
|
||||
#Mon Aug 13 12:00:31 EDT 2007
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.3
|
||||
@@ -142,7 +142,7 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.indentation.size=8
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
@@ -322,7 +322,7 @@ org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=mixed
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=8
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
|
||||
@@ -1,60 +1,56 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.definition.registry;
|
||||
|
||||
import org.springframework.webflow.definition.FlowDefinition;
|
||||
|
||||
/**
|
||||
* A container of flow definitions. Extends the {@link FlowDefinitionRegistryMBean}
|
||||
* management interface exposing registry monitoring and management operations.
|
||||
* Also extends {@link FlowDefinitionLocator} for accessing registered Flow
|
||||
* definitions for execution at runtime.
|
||||
* <p>
|
||||
* Flow definition registries can be configured with a "parent" registry to provide a hook
|
||||
* into a larger flow definition registry hierarchy.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface FlowDefinitionRegistry extends FlowDefinitionLocator, FlowDefinitionRegistryMBean {
|
||||
|
||||
/**
|
||||
* Sets this registry's parent registry. When asked by a client to locate a
|
||||
* flow definition this registry will query it's parent if it cannot
|
||||
* fullfill the lookup request itself.
|
||||
* @param parent the parent flow definition registry, may be null
|
||||
*/
|
||||
public void setParent(FlowDefinitionRegistry parent);
|
||||
|
||||
/**
|
||||
* Return all flow definitions registered in this registry. Note that this
|
||||
* will trigger flow assemply for all registered flow definitions (which may
|
||||
* be expensive).
|
||||
* @return the flow definitions
|
||||
* @throws FlowDefinitionConstructionException if there is a problem constructing
|
||||
* one of the registered flow definitions
|
||||
*/
|
||||
public FlowDefinition[] getFlowDefinitions() throws FlowDefinitionConstructionException;
|
||||
|
||||
/**
|
||||
* Register a flow definition in this registry. Registers a "holder", not
|
||||
* the Flow definition itself. This allows the actual Flow definition to be
|
||||
* loaded lazily only when needed, and also rebuilt at runtime when its
|
||||
* underlying resource changes without redeploy.
|
||||
* @param flowHolder a holder holding the flow definition to register
|
||||
*/
|
||||
public void registerFlowDefinition(FlowDefinitionHolder flowHolder);
|
||||
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.definition.registry;
|
||||
|
||||
import org.springframework.webflow.definition.FlowDefinition;
|
||||
|
||||
/**
|
||||
* A container of flow definitions. Extends the {@link FlowDefinitionRegistryMBean} management interface exposing
|
||||
* registry monitoring and management operations. Also extends {@link FlowDefinitionLocator} for accessing registered
|
||||
* Flow definitions for execution at runtime.
|
||||
* <p>
|
||||
* Flow definition registries can be configured with a "parent" registry to provide a hook into a larger flow definition
|
||||
* registry hierarchy.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface FlowDefinitionRegistry extends FlowDefinitionLocator, FlowDefinitionRegistryMBean {
|
||||
|
||||
/**
|
||||
* Sets this registry's parent registry. When asked by a client to locate a flow definition this registry will query
|
||||
* it's parent if it cannot fulfill the lookup request itself.
|
||||
* @param parent the parent flow definition registry, may be null
|
||||
*/
|
||||
public void setParent(FlowDefinitionRegistry parent);
|
||||
|
||||
/**
|
||||
* Return all flow definitions registered in this registry. Note that this will trigger flow assembly for all
|
||||
* registered flow definitions (which may be expensive).
|
||||
* @return the flow definitions
|
||||
* @throws FlowDefinitionConstructionException if there is a problem constructing one of the registered flow
|
||||
* definitions
|
||||
*/
|
||||
public FlowDefinition[] getFlowDefinitions() throws FlowDefinitionConstructionException;
|
||||
|
||||
/**
|
||||
* Register a flow definition in this registry. Registers a "holder", not the Flow definition itself. This allows
|
||||
* the actual Flow definition to be loaded lazily only when needed, and also rebuilt at runtime when its underlying
|
||||
* resource changes without redeploy.
|
||||
* @param flowHolder a holder holding the flow definition to register
|
||||
*/
|
||||
public void registerFlowDefinition(FlowDefinitionHolder flowHolder);
|
||||
|
||||
}
|
||||
@@ -1,235 +1,233 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.definition.registry;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.definition.FlowDefinition;
|
||||
|
||||
/**
|
||||
* A generic registry implementation for housing one or more flow definitions.
|
||||
* <p>
|
||||
* This registry may be refreshed at runtime to "hot reload" refreshable flow
|
||||
* definitions. Note that the refresh will only reload already registered
|
||||
* flow definitions but will not detect any new flow definitions or remove
|
||||
* flow definitions that no longer exist.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class FlowDefinitionRegistryImpl implements FlowDefinitionRegistry {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowDefinitionRegistryImpl.class);
|
||||
|
||||
/**
|
||||
* The map of loaded Flow definitions maintained in this registry.
|
||||
*/
|
||||
private Map flowDefinitions = new TreeMap();
|
||||
|
||||
/**
|
||||
* An optional parent flow definition registry.
|
||||
*/
|
||||
private FlowDefinitionRegistry parent;
|
||||
|
||||
// implementing FlowDefinitionRegistryMBean
|
||||
|
||||
public String[] getFlowDefinitionIds() {
|
||||
return (String[])flowDefinitions.keySet().toArray(new String[flowDefinitions.size()]);
|
||||
}
|
||||
|
||||
public int getFlowDefinitionCount() {
|
||||
return flowDefinitions.size();
|
||||
}
|
||||
|
||||
public boolean containsFlowDefinition(String id) {
|
||||
Assert.hasText(id, "The flow id is required");
|
||||
return flowDefinitions.get(id) != null;
|
||||
}
|
||||
|
||||
public void refresh() throws FlowDefinitionConstructionException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Refreshing flow definition registry '" + this + "'");
|
||||
}
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// workaround for JMX
|
||||
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
|
||||
LinkedList needsReindexing = new LinkedList();
|
||||
Iterator it = flowDefinitions.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)it.next();
|
||||
String key = (String)entry.getKey();
|
||||
FlowDefinitionHolder holder = (FlowDefinitionHolder)entry.getValue();
|
||||
holder.refresh();
|
||||
if (!holder.getFlowDefinitionId().equals(key)) {
|
||||
needsReindexing.add(new Indexed(key, holder));
|
||||
}
|
||||
}
|
||||
it = needsReindexing.iterator();
|
||||
while (it.hasNext()) {
|
||||
Indexed indexed = (Indexed)it.next();
|
||||
reindex(indexed.holder, indexed.key);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh(String flowId)
|
||||
throws NoSuchFlowDefinitionException, FlowDefinitionConstructionException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Refreshing flow with id '" + flowId + "'");
|
||||
}
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// workaround for JMX
|
||||
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
|
||||
FlowDefinitionHolder holder = getFlowDefinitionHolder(flowId);
|
||||
holder.refresh();
|
||||
if (!holder.getFlowDefinitionId().equals(flowId)) {
|
||||
reindex(holder, flowId);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
}
|
||||
|
||||
// implementing FlowDefinitionLocator
|
||||
|
||||
public FlowDefinition getFlowDefinition(String id)
|
||||
throws NoSuchFlowDefinitionException, FlowDefinitionConstructionException {
|
||||
Assert.hasText(id,
|
||||
"Unable to load a flow definition: no flow id was provided. Please provide a valid flow identifier.");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Getting flow definition with id '" + id + "'");
|
||||
}
|
||||
try {
|
||||
return getFlowDefinitionHolder(id).getFlowDefinition();
|
||||
}
|
||||
catch (NoSuchFlowDefinitionException e) {
|
||||
if (parent != null) {
|
||||
// try parent
|
||||
return parent.getFlowDefinition(id);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// implementing FlowDefinitionRegistry
|
||||
|
||||
public void setParent(FlowDefinitionRegistry parent) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Setting parent flow definition registry to '" + parent + "'");
|
||||
}
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public FlowDefinition[] getFlowDefinitions() throws FlowDefinitionConstructionException {
|
||||
FlowDefinition[] flows = new FlowDefinition[flowDefinitions.size()];
|
||||
Iterator it = flowDefinitions.values().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
FlowDefinitionHolder holder = (FlowDefinitionHolder)it.next();
|
||||
flows[i] = holder.getFlowDefinition();
|
||||
i++;
|
||||
}
|
||||
return flows;
|
||||
}
|
||||
|
||||
public void registerFlowDefinition(FlowDefinitionHolder flowHolder) {
|
||||
Assert.notNull(flowHolder, "The flow definition holder to register is required");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Registering flow definition with id '" + flowHolder.getFlowDefinitionId() + "'");
|
||||
}
|
||||
index(flowHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove identified flow definition from this registry. If the given
|
||||
* id is not known in this registry, nothing will happen.
|
||||
* @param id the flow definition id
|
||||
*/
|
||||
public void removeFlowDefinition(String id) {
|
||||
Assert.hasText(id, "The flow id is required");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Removing flow definition with id '" + id + "'");
|
||||
}
|
||||
flowDefinitions.remove(id);
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
/**
|
||||
* Reindex given flow definition.
|
||||
* @param holder the holder holding the flow definition to reindex
|
||||
* @param oldId the id that was previously assigned to given flow definition
|
||||
*/
|
||||
private void reindex(FlowDefinitionHolder holder, String oldId) {
|
||||
flowDefinitions.remove(oldId);
|
||||
index(holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Index given flow definition.
|
||||
* @param holder the holder holding the flow definition to index
|
||||
*/
|
||||
private void index(FlowDefinitionHolder holder) {
|
||||
Assert.hasText(holder.getFlowDefinitionId(), "The flow holder to index must return a non-blank flow id");
|
||||
flowDefinitions.put(holder.getFlowDefinitionId(), holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identified flow definition holder. Throws an exception
|
||||
* if it cannot be found.
|
||||
*/
|
||||
private FlowDefinitionHolder getFlowDefinitionHolder(String id) throws NoSuchFlowDefinitionException {
|
||||
FlowDefinitionHolder flowHolder = (FlowDefinitionHolder)flowDefinitions.get(id);
|
||||
if (flowHolder == null) {
|
||||
throw new NoSuchFlowDefinitionException(id, getFlowDefinitionIds());
|
||||
}
|
||||
return flowHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple value object that holds the key for an indexed flow definition
|
||||
* holder in this registry. Used to support reindexing on a refresh.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
private static class Indexed {
|
||||
|
||||
private String key;
|
||||
|
||||
private FlowDefinitionHolder holder;
|
||||
|
||||
public Indexed(String key, FlowDefinitionHolder holder) {
|
||||
this.key = key;
|
||||
this.holder = holder;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("flowDefinitions", flowDefinitions).append("parent", parent).toString();
|
||||
}
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.definition.registry;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.definition.FlowDefinition;
|
||||
|
||||
/**
|
||||
* A generic registry implementation for housing one or more flow definitions.
|
||||
* <p>
|
||||
* This registry may be refreshed at runtime to "hot reload" refreshable flow definitions. Note that the refresh will
|
||||
* only reload already registered flow definitions but will not detect any new flow definitions or remove flow
|
||||
* definitions that no longer exist.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class FlowDefinitionRegistryImpl implements FlowDefinitionRegistry {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FlowDefinitionRegistryImpl.class);
|
||||
|
||||
/**
|
||||
* The map of loaded Flow definitions maintained in this registry.
|
||||
*/
|
||||
private Map flowDefinitions;
|
||||
|
||||
/**
|
||||
* An optional parent flow definition registry.
|
||||
*/
|
||||
private FlowDefinitionRegistry parent;
|
||||
|
||||
public FlowDefinitionRegistryImpl() {
|
||||
flowDefinitions = new TreeMap();
|
||||
}
|
||||
|
||||
// implementing FlowDefinitionRegistryMBean
|
||||
|
||||
public String[] getFlowDefinitionIds() {
|
||||
return (String[]) flowDefinitions.keySet().toArray(new String[flowDefinitions.size()]);
|
||||
}
|
||||
|
||||
public int getFlowDefinitionCount() {
|
||||
return flowDefinitions.size();
|
||||
}
|
||||
|
||||
public boolean containsFlowDefinition(String id) {
|
||||
Assert.hasText(id, "The flow id is required");
|
||||
return flowDefinitions.get(id) != null;
|
||||
}
|
||||
|
||||
public void refresh() throws FlowDefinitionConstructionException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Refreshing flow definition registry '" + this + "'");
|
||||
}
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// workaround for JMX
|
||||
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
|
||||
LinkedList needsReindexing = new LinkedList();
|
||||
Iterator it = flowDefinitions.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry) it.next();
|
||||
String key = (String) entry.getKey();
|
||||
FlowDefinitionHolder holder = (FlowDefinitionHolder) entry.getValue();
|
||||
holder.refresh();
|
||||
if (!holder.getFlowDefinitionId().equals(key)) {
|
||||
needsReindexing.add(new Indexed(key, holder));
|
||||
}
|
||||
}
|
||||
it = needsReindexing.iterator();
|
||||
while (it.hasNext()) {
|
||||
Indexed indexed = (Indexed) it.next();
|
||||
reindex(indexed.holder, indexed.key);
|
||||
}
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh(String flowId) throws NoSuchFlowDefinitionException, FlowDefinitionConstructionException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Refreshing flow with id '" + flowId + "'");
|
||||
}
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// workaround for JMX
|
||||
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
|
||||
FlowDefinitionHolder holder = getFlowDefinitionHolder(flowId);
|
||||
holder.refresh();
|
||||
if (!holder.getFlowDefinitionId().equals(flowId)) {
|
||||
reindex(holder, flowId);
|
||||
}
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
}
|
||||
|
||||
// implementing FlowDefinitionLocator
|
||||
|
||||
public FlowDefinition getFlowDefinition(String id) throws NoSuchFlowDefinitionException,
|
||||
FlowDefinitionConstructionException {
|
||||
Assert.hasText(id,
|
||||
"Unable to load a flow definition: no flow id was provided. Please provide a valid flow identifier.");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Getting flow definition with id '" + id + "'");
|
||||
}
|
||||
try {
|
||||
return getFlowDefinitionHolder(id).getFlowDefinition();
|
||||
} catch (NoSuchFlowDefinitionException e) {
|
||||
if (parent != null) {
|
||||
// try parent
|
||||
return parent.getFlowDefinition(id);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// implementing FlowDefinitionRegistry
|
||||
|
||||
public void setParent(FlowDefinitionRegistry parent) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Setting parent flow definition registry to '" + parent + "'");
|
||||
}
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public FlowDefinition[] getFlowDefinitions() throws FlowDefinitionConstructionException {
|
||||
FlowDefinition[] flows = new FlowDefinition[flowDefinitions.size()];
|
||||
Iterator it = flowDefinitions.values().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
FlowDefinitionHolder holder = (FlowDefinitionHolder) it.next();
|
||||
flows[i] = holder.getFlowDefinition();
|
||||
i++;
|
||||
}
|
||||
return flows;
|
||||
}
|
||||
|
||||
public void registerFlowDefinition(FlowDefinitionHolder flowHolder) {
|
||||
Assert.notNull(flowHolder, "The flow definition holder to register is required");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Registering flow definition with id '" + flowHolder.getFlowDefinitionId() + "'");
|
||||
}
|
||||
index(flowHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove identified flow definition from this registry. If the given id is not known in this registry, nothing will
|
||||
* happen.
|
||||
* @param id the flow definition id
|
||||
*/
|
||||
public void removeFlowDefinition(String id) {
|
||||
Assert.hasText(id, "The flow id is required");
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Removing flow definition with id '" + id + "'");
|
||||
}
|
||||
flowDefinitions.remove(id);
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
/**
|
||||
* Reindex given flow definition.
|
||||
* @param holder the holder holding the flow definition to reindex
|
||||
* @param oldId the id that was previously assigned to given flow definition
|
||||
*/
|
||||
private void reindex(FlowDefinitionHolder holder, String oldId) {
|
||||
flowDefinitions.remove(oldId);
|
||||
index(holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Index given flow definition.
|
||||
* @param holder the holder holding the flow definition to index
|
||||
*/
|
||||
private void index(FlowDefinitionHolder holder) {
|
||||
Assert.hasText(holder.getFlowDefinitionId(), "The flow holder to index must return a non-blank flow id");
|
||||
flowDefinitions.put(holder.getFlowDefinitionId(), holder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identified flow definition holder. Throws an exception if it cannot be found.
|
||||
*/
|
||||
private FlowDefinitionHolder getFlowDefinitionHolder(String id) throws NoSuchFlowDefinitionException {
|
||||
FlowDefinitionHolder flowHolder = (FlowDefinitionHolder) flowDefinitions.get(id);
|
||||
if (flowHolder == null) {
|
||||
throw new NoSuchFlowDefinitionException(id, getFlowDefinitionIds());
|
||||
}
|
||||
return flowHolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple value object that holds the key for an indexed flow definition holder in this registry. Used to support
|
||||
* reindexing on a refresh.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
private static class Indexed {
|
||||
|
||||
private String key;
|
||||
|
||||
private FlowDefinitionHolder holder;
|
||||
|
||||
public Indexed(String key, FlowDefinitionHolder holder) {
|
||||
this.key = key;
|
||||
this.holder = holder;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("flowDefinitions", flowDefinitions).append("parent", parent).toString();
|
||||
}
|
||||
}
|
||||
@@ -1,118 +1,111 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.engine.support;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
|
||||
/**
|
||||
* Expression evaluator that can evalute attribute maps and supported
|
||||
* request context scope types.
|
||||
*
|
||||
* @see org.springframework.webflow.execution.RequestContext
|
||||
* @see org.springframework.webflow.core.collection.AttributeMap
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
public class AttributeExpression implements SettableExpression {
|
||||
|
||||
/**
|
||||
* The expression to evaluate.
|
||||
*/
|
||||
private Expression expression;
|
||||
|
||||
/**
|
||||
* The scope type.
|
||||
*/
|
||||
private ScopeType scopeType;
|
||||
|
||||
/**
|
||||
* Create a new expression evaluator that executes given expression in an
|
||||
* attribute map. When using this wrapper to set a property value, make
|
||||
* sure the given expression is a {@link SettableExpression}}.
|
||||
* @param expression the nested evaluator to execute
|
||||
*/
|
||||
public AttributeExpression(Expression expression) {
|
||||
this(expression, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new expression evaluator that executes given expression in the
|
||||
* specified scope. When using this wrapper to set a property value, make
|
||||
* sure the given expression is a {@link SettableExpression}}.
|
||||
* @param expression the nested evaluator to execute
|
||||
* @param scopeType the scopeType
|
||||
*/
|
||||
public AttributeExpression(Expression expression, ScopeType scopeType) {
|
||||
this.expression = expression;
|
||||
this.scopeType = scopeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expression that will be evaluated.
|
||||
*/
|
||||
protected Expression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
if (target instanceof RequestContext) {
|
||||
RequestContext requestContext = (RequestContext)target;
|
||||
AttributeMap scope = scopeType.getScope(requestContext);
|
||||
return expression.evaluate(scope, context);
|
||||
}
|
||||
else if (target instanceof AttributeMap) {
|
||||
return expression.evaluate(target, context);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Only supports evaluation against a [RequestContext] or [AttributeMap] instance, but was a ["
|
||||
+ target.getClass() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
|
||||
Assert.isInstanceOf(SettableExpression.class, expression,
|
||||
"When an AttributeExpression is used to set a property value, the nested expression needs "
|
||||
+ "to be a SettableExpression");
|
||||
if (target instanceof RequestContext) {
|
||||
RequestContext requestContext = (RequestContext)target;
|
||||
MutableAttributeMap scope = scopeType.getScope(requestContext);
|
||||
((SettableExpression)expression).evaluateToSet(scope, value, context);
|
||||
}
|
||||
else if (target instanceof AttributeMap) {
|
||||
((SettableExpression)expression).evaluateToSet(target, value, context);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Only supports evaluation against a [RequestContext] or [AttributeMap] instance, but was a ["
|
||||
+ target.getClass() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("expression", expression).toString();
|
||||
}
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.engine.support;
|
||||
|
||||
import org.springframework.binding.expression.EvaluationContext;
|
||||
import org.springframework.binding.expression.EvaluationException;
|
||||
import org.springframework.binding.expression.Expression;
|
||||
import org.springframework.binding.expression.SettableExpression;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
|
||||
/**
|
||||
* Expression evaluator that can evaluate attribute maps and supported request context scope types.
|
||||
*
|
||||
* @see org.springframework.webflow.execution.RequestContext
|
||||
* @see org.springframework.webflow.core.collection.AttributeMap
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
public class AttributeExpression implements SettableExpression {
|
||||
|
||||
/**
|
||||
* The expression to evaluate.
|
||||
*/
|
||||
private Expression expression;
|
||||
|
||||
/**
|
||||
* The scope type.
|
||||
*/
|
||||
private ScopeType scopeType;
|
||||
|
||||
/**
|
||||
* Create a new expression evaluator that executes given expression in an attribute map. When using this wrapper to
|
||||
* set a property value, make sure the given expression is a {@link SettableExpression}}.
|
||||
* @param expression the nested evaluator to execute
|
||||
*/
|
||||
public AttributeExpression(Expression expression) {
|
||||
this(expression, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new expression evaluator that executes given expression in the specified scope. When using this wrapper
|
||||
* to set a property value, make sure the given expression is a {@link SettableExpression}}.
|
||||
* @param expression the nested evaluator to execute
|
||||
* @param scopeType the scopeType
|
||||
*/
|
||||
public AttributeExpression(Expression expression, ScopeType scopeType) {
|
||||
this.expression = expression;
|
||||
this.scopeType = scopeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expression that will be evaluated.
|
||||
*/
|
||||
protected Expression getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
|
||||
if (target instanceof RequestContext) {
|
||||
RequestContext requestContext = (RequestContext) target;
|
||||
AttributeMap scope = scopeType.getScope(requestContext);
|
||||
return expression.evaluate(scope, context);
|
||||
} else if (target instanceof AttributeMap) {
|
||||
return expression.evaluate(target, context);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Only supports evaluation against a [RequestContext] or [AttributeMap] instance, but was a ["
|
||||
+ target.getClass() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
|
||||
Assert.isInstanceOf(SettableExpression.class, expression,
|
||||
"When an AttributeExpression is used to set a property value, the nested expression needs "
|
||||
+ "to be a SettableExpression");
|
||||
if (target instanceof RequestContext) {
|
||||
RequestContext requestContext = (RequestContext) target;
|
||||
MutableAttributeMap scope = scopeType.getScope(requestContext);
|
||||
((SettableExpression) expression).evaluateToSet(scope, value, context);
|
||||
} else if (target instanceof AttributeMap) {
|
||||
((SettableExpression) expression).evaluateToSet(target, value, context);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Only supports evaluation against a [RequestContext] or [AttributeMap] instance, but was a ["
|
||||
+ target.getClass() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("expression", expression).toString();
|
||||
}
|
||||
}
|
||||
@@ -1,87 +1,84 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.engine.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.engine.TransitionCriteria;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Simple transition criteria that matches on an eventId and nothing else.
|
||||
* Specifically, if the id of the last event that occured equals
|
||||
* {@link #getEventId()} this criteria will return true.
|
||||
*
|
||||
* @see RequestContext#getLastEvent()
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class EventIdTransitionCriteria implements TransitionCriteria, Serializable {
|
||||
|
||||
/**
|
||||
* The event id to match.
|
||||
*/
|
||||
private String eventId;
|
||||
|
||||
/**
|
||||
* Whether or not to match case sensitively. Default is true.
|
||||
*/
|
||||
private boolean caseSensitive = true;
|
||||
|
||||
/**
|
||||
* Create a new event id matching criteria object.
|
||||
* @param eventId the event id
|
||||
*/
|
||||
public EventIdTransitionCriteria(String eventId) {
|
||||
Assert.hasText(eventId, "The event id is required");
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event id to match.
|
||||
*/
|
||||
public String getEventId() {
|
||||
return eventId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the event id should be matched in a case sensitve
|
||||
* manner. Defaults to true.
|
||||
*/
|
||||
public void setCaseSensitive(boolean caseSensitive) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
}
|
||||
|
||||
public boolean test(RequestContext context) {
|
||||
Event lastEvent = context.getLastEvent();
|
||||
if (lastEvent == null) {
|
||||
return false;
|
||||
}
|
||||
if (caseSensitive) {
|
||||
return eventId.equals(lastEvent.getId());
|
||||
}
|
||||
else {
|
||||
return eventId.equalsIgnoreCase(lastEvent.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[eventId = '" + eventId + "']";
|
||||
}
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.engine.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.engine.TransitionCriteria;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
/**
|
||||
* Simple transition criteria that matches on an eventId and nothing else. Specifically, if the id of the last event
|
||||
* that occurred equals {@link #getEventId()} this criteria will return true.
|
||||
*
|
||||
* @see RequestContext#getLastEvent()
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class EventIdTransitionCriteria implements TransitionCriteria, Serializable {
|
||||
|
||||
/**
|
||||
* The event id to match.
|
||||
*/
|
||||
private String eventId;
|
||||
|
||||
/**
|
||||
* Whether or not to match case sensitively. Default is true.
|
||||
*/
|
||||
private boolean caseSensitive = true;
|
||||
|
||||
/**
|
||||
* Create a new event id matching criteria object.
|
||||
* @param eventId the event id
|
||||
*/
|
||||
public EventIdTransitionCriteria(String eventId) {
|
||||
Assert.hasText(eventId, "The event id is required");
|
||||
this.eventId = eventId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event id to match.
|
||||
*/
|
||||
public String getEventId() {
|
||||
return eventId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the event id should be matched in a case sensitive manner. Defaults to true.
|
||||
*/
|
||||
public void setCaseSensitive(boolean caseSensitive) {
|
||||
this.caseSensitive = caseSensitive;
|
||||
}
|
||||
|
||||
public boolean test(RequestContext context) {
|
||||
Event lastEvent = context.getLastEvent();
|
||||
if (lastEvent == null) {
|
||||
return false;
|
||||
}
|
||||
if (caseSensitive) {
|
||||
return eventId.equals(lastEvent.getId());
|
||||
} else {
|
||||
return eventId.equalsIgnoreCase(lastEvent.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[eventId = '" + eventId + "']";
|
||||
}
|
||||
}
|
||||
@@ -1,112 +1,104 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.util;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Simple utility class for working with the java reflection API. Only intended for
|
||||
* internal use. Will likely disappear in a future release of Spring Web Flow and
|
||||
* simply rely on {@link org.springframework.util.ReflectionUtils} if necessary.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ReflectionUtils {
|
||||
|
||||
/**
|
||||
* Invoke the specified {@link Method} against the supplied target object
|
||||
* with no arguments. The target object can be <code>null</code> when
|
||||
* invoking a static {@link Method}. All exceptions are treated as fatal and will be
|
||||
* converted to unchecked exceptions.
|
||||
* @see #invokeMethod(java.lang.reflect.Method, Object, Object[])
|
||||
* @throws RuntimeException when something goes wrong invoking the method or
|
||||
* when the method itself throws an exception
|
||||
*/
|
||||
public static Object invokeMethod(Method method, Object target) throws RuntimeException {
|
||||
return invokeMethod(method, target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the specified {@link Method} against the supplied target object
|
||||
* with the supplied arguments. The target object can be null when invoking a
|
||||
* static {@link Method}. All exceptions are treated as fatal and will be
|
||||
* converted to unchecked exceptions.
|
||||
* @see #invokeMethod(java.lang.reflect.Method, Object, Object[])
|
||||
* @throws RuntimeException when something goes wrong invoking the method or
|
||||
* when the method itself throws an exception
|
||||
*/
|
||||
public static Object invokeMethod(Method method, Object target, Object[] args) throws RuntimeException {
|
||||
try {
|
||||
return method.invoke(target, args);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
handleReflectionException(ex);
|
||||
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
handleReflectionException(ex);
|
||||
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the given reflection exception.
|
||||
* Should only be called if no checked exception is expected to
|
||||
* be thrown by the target method.
|
||||
* <p>
|
||||
* Throws the underlying RuntimeException or Error in case
|
||||
* of an InvocationTargetException with such a root cause. Throws
|
||||
* an IllegalStateException with an appropriate message else.
|
||||
* @param ex the reflection exception to handle
|
||||
*/
|
||||
private static void handleReflectionException(Exception ex) {
|
||||
if (ex instanceof NoSuchMethodException) {
|
||||
throw new IllegalStateException("Method not found: " + ex.getMessage());
|
||||
}
|
||||
if (ex instanceof IllegalAccessException) {
|
||||
throw new IllegalStateException("Could not access method: " + ex.getMessage());
|
||||
}
|
||||
if (ex instanceof InvocationTargetException) {
|
||||
handleInvocationTargetException((InvocationTargetException) ex);
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the given invocation target exception.
|
||||
* Should only be called if no checked exception is expected to
|
||||
* be thrown by the target method.
|
||||
* <p>
|
||||
* Throws the underlying RuntimeException or Error in case
|
||||
* of such a root cause. Throws an IllegalStateException else.
|
||||
* @param ex the invocation target exception to handle
|
||||
*/
|
||||
private static void handleInvocationTargetException(InvocationTargetException ex) {
|
||||
if (ex.getTargetException() instanceof RuntimeException) {
|
||||
throw (RuntimeException) ex.getTargetException();
|
||||
}
|
||||
if (ex.getTargetException() instanceof Error) {
|
||||
throw (Error) ex.getTargetException();
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Unexpected exception thrown by method - " + ex.getTargetException().getClass().getName() +
|
||||
": " + ex.getTargetException().getMessage());
|
||||
}
|
||||
/*
|
||||
* Copyright 2004-2007 the original author 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.springframework.webflow.util;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Simple utility class for working with the java reflection API. Only intended for internal use. Will likely disappear
|
||||
* in a future release of Spring Web Flow and simply rely on {@link org.springframework.util.ReflectionUtils} if
|
||||
* necessary.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ReflectionUtils {
|
||||
|
||||
/**
|
||||
* Invoke the specified {@link Method} against the supplied target object with no arguments. The target object can
|
||||
* be <code>null</code> when invoking a static {@link Method}. All exceptions are treated as fatal and will be
|
||||
* converted to unchecked exceptions.
|
||||
* @see #invokeMethod(java.lang.reflect.Method, Object, Object[])
|
||||
* @throws RuntimeException when something goes wrong invoking the method or when the method itself throws an
|
||||
* exception
|
||||
*/
|
||||
public static Object invokeMethod(Method method, Object target) throws RuntimeException {
|
||||
return invokeMethod(method, target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the specified {@link Method} against the supplied target object with the supplied arguments. The target
|
||||
* object can be null when invoking a static {@link Method}. All exceptions are treated as fatal and will be
|
||||
* converted to unchecked exceptions.
|
||||
* @see #invokeMethod(java.lang.reflect.Method, Object, Object[])
|
||||
* @throws RuntimeException when something goes wrong invoking the method or when the method itself throws an
|
||||
* exception
|
||||
*/
|
||||
public static Object invokeMethod(Method method, Object target, Object[] args) throws RuntimeException {
|
||||
try {
|
||||
return method.invoke(target, args);
|
||||
} catch (IllegalAccessException ex) {
|
||||
handleReflectionException(ex);
|
||||
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||
+ ex.getMessage());
|
||||
} catch (InvocationTargetException ex) {
|
||||
handleReflectionException(ex);
|
||||
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the given reflection exception. Should only be called if no checked exception is expected to be thrown by
|
||||
* the target method.
|
||||
* <p>
|
||||
* Throws the underlying RuntimeException or Error in case of an InvocationTargetException with such a root cause.
|
||||
* Throws an IllegalStateException with an appropriate message else.
|
||||
* @param ex the reflection exception to handle
|
||||
*/
|
||||
private static void handleReflectionException(Exception ex) {
|
||||
if (ex instanceof NoSuchMethodException) {
|
||||
throw new IllegalStateException("Method not found: " + ex.getMessage());
|
||||
}
|
||||
if (ex instanceof IllegalAccessException) {
|
||||
throw new IllegalStateException("Could not access method: " + ex.getMessage());
|
||||
}
|
||||
if (ex instanceof InvocationTargetException) {
|
||||
handleInvocationTargetException((InvocationTargetException) ex);
|
||||
}
|
||||
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the given invocation target exception. Should only be called if no checked exception is expected to be
|
||||
* thrown by the target method.
|
||||
* <p>
|
||||
* Throws the underlying RuntimeException or Error in case of such a root cause. Throws an IllegalStateException
|
||||
* else.
|
||||
* @param ex the invocation target exception to handle
|
||||
*/
|
||||
private static void handleInvocationTargetException(InvocationTargetException ex) {
|
||||
if (ex.getTargetException() instanceof RuntimeException) {
|
||||
throw (RuntimeException) ex.getTargetException();
|
||||
}
|
||||
if (ex.getTargetException() instanceof Error) {
|
||||
throw (Error) ex.getTargetException();
|
||||
}
|
||||
throw new IllegalStateException("Unexpected exception thrown by method - "
|
||||
+ ex.getTargetException().getClass().getName() + ": " + ex.getTargetException().getMessage());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user