package file updates
removed unused / old code
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.util;
|
||||
package org.springframework.webflow.action;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -32,7 +32,7 @@ import org.springframework.util.CachingMapDecorator;
|
||||
* @author Keith Donald
|
||||
* @author Ben Hale
|
||||
*/
|
||||
public class DispatchMethodInvoker {
|
||||
class DispatchMethodInvoker {
|
||||
|
||||
/**
|
||||
* The target object to dispatch to.
|
||||
@@ -33,7 +33,6 @@ import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
import org.springframework.webflow.util.DispatchMethodInvoker;
|
||||
|
||||
/**
|
||||
* Multi-action that implements common logic dealing with input forms. This class leverages the Spring Web data binding
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.webflow.action;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.util.DispatchMethodInvoker;
|
||||
|
||||
/**
|
||||
* Action implementation that bundles two or more action execution methods into a single class. Action execution methods
|
||||
|
||||
@@ -8,8 +8,5 @@ When implementing custom actions, consider subclassing {@link org.springframewor
|
||||
Alternatively, you could also subclass {@link org.springframework.webflow.action.MultiAction} to bundle several action
|
||||
execution methods in a single class.
|
||||
</p>
|
||||
<p>
|
||||
The {@link org.springframework.webflow.action.FormAction} provides powerful input form handling functionality.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -8,8 +8,7 @@ This is the highest-layer package in the framework, responsible for providing
|
||||
a clean interface for configuring Spring Web Flow.
|
||||
</p>
|
||||
<p>
|
||||
This package also defines a Spring 2.0 custom XML namespace for configuring
|
||||
the Spring Web Flow engine in a Spring 2.0 environment.
|
||||
This package also defines a Spring custom XML namespace for configuring the Spring Web Flow engine.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Support code to allow access to the Spring Web Flow scopes (request, flash, flow conversation) from a Spring ApplicationContext.
|
||||
Web Flow custom bean scopes allowing access to scoped-beans from a Spring ApplicationContext.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Contains the PortletExternalContext implementation for calling into Web Flow from a Portlet.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
The representation of a client request into Spring Web Flow from an HTTP Servlet environment.
|
||||
Contains the ServletExternalContext implementation for calling into Web Flow from a Servlet environment.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Shared classes used by the Servlet and Portlet ExternalContext implementations.
|
||||
</body>
|
||||
</html>
|
||||
@@ -9,11 +9,8 @@ The central concept defined by this package is the
|
||||
a service interface for managing conversations.
|
||||
</p>
|
||||
<p>
|
||||
This package serves as a portable conversation management abstraction and does not depend on
|
||||
the Spring Web Flow engine. It is used by the flow execution repository subsystem to store conversation related
|
||||
state. It is important to realize that this subsystem does not define a conceptual <i>conversation</i>,
|
||||
it just servers as a technical layer to manage state associated with conversations, as implemented by the
|
||||
SWF engine.
|
||||
This package serves as a portable conversation management abstraction and does not depend on the Spring Web Flow engine.
|
||||
It is used by the flow execution repository subsystem to store conversation related state.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,37 +5,12 @@ Core, stable abstractions for representing flow definitions.
|
||||
</p>
|
||||
<p>
|
||||
Each flow has an indentifier and is composed of one or more states, one of which is the start state.
|
||||
States may be transitionable, and if so define one or more transitions that lead to other states.
|
||||
States may be transitionable, if so they define one or more transitions that lead to other states.
|
||||
</p>
|
||||
<p>
|
||||
With these types a client can introspect a flow definition to reason on its attributes and traverse
|
||||
its structure, perhaps to display a visual diagram. Note that the types defined in this package
|
||||
do not capture the behavioral characteristics of a flow.
|
||||
</p>
|
||||
<p>
|
||||
The following code shows the beginnings of a basic flow definition traversal algorithm:
|
||||
</p>
|
||||
<pre class="code">
|
||||
FlowDefinition flow = ...
|
||||
|
||||
// lookup start state
|
||||
StateDefinition state = flow.getStartState();
|
||||
|
||||
// traverse to state transitions
|
||||
traverse(state);
|
||||
|
||||
public void traverse(StateDefinition state) {
|
||||
logger.info("State: " + state.getId());
|
||||
while (state instanceof TransitionableStateDefinition) {
|
||||
TransitionableStateDefinition transitionable = (TransitionableStateDefinition)state;
|
||||
TransitionDefinition[] transitions = transitionable.getTransitions();
|
||||
for (int i = 0; i < transitions.length; i++) {
|
||||
Transition t = transitions[i];
|
||||
logger.info("Transition " + t.getId());
|
||||
traverse(state.getOwner().getState(t.getTargetStateId());
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,25 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The flow definition registry subsystem for managing containers of flow definitions.
|
||||
The flow definition registry subsystem for managing collections of executable flow definitions.
|
||||
</p>
|
||||
<p>
|
||||
You can construct a generic, initially empty FlowDefinitionRegistry, populate it
|
||||
with flow definitions using a FlowDefinitionRegistrar, then lookup flow definitions by id.
|
||||
For example:
|
||||
</p>
|
||||
<pre class="code">
|
||||
// create registry
|
||||
FlowDefinitionRegistry registry = new FlowDefinitionRegistryImpl();
|
||||
|
||||
// populate registry
|
||||
FlowDefinitionRegistrar registrar = ..
|
||||
registrar.addLocation(...);
|
||||
registrar.addLocation(...);
|
||||
registrar.registerFlowDefinitions(registry);
|
||||
|
||||
// use registry
|
||||
FlowDefinition flow = registry.getFlow("myFlow");
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Contains a FlowBuilder that builds {@link org.springframework.webflow.engine.Flow} instances from a
|
||||
{@link org.springframework.webflow.engine.model.FlowModel}.
|
||||
</p>
|
||||
<p>
|
||||
A FLowModel is a generic Java-based configuration model of a Flow, independent of any
|
||||
external representation such as an XML file. Therefore, the FlowBuilder in this package may
|
||||
engineer Flows from models produced from different representations.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,34 +1,12 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The flow builder subsystem for building and assembling executable flow definitions.
|
||||
The FlowBuilder subsystem for building and assembling executable flow definitions.
|
||||
</p>
|
||||
<p>
|
||||
You construct a Flow using a {@link org.springframework.webflow.engine.builder.FlowBuilder}.
|
||||
This package defines the following flow builder implementations:
|
||||
<ul>
|
||||
<li>
|
||||
{@link org.springframework.webflow.engine.builder.AbstractFlowBuilder} - A
|
||||
convenience superclass to use when you want to assemble the web flow
|
||||
in Java code.
|
||||
</li>
|
||||
<li>
|
||||
{@link org.springframework.webflow.engine.builder.xml.XmlFlowBuilder} - A flow
|
||||
builder that reads an XML file containing a web flow definition and
|
||||
constructs the flow accordingly.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
During flow construction, a flow builder may need to access externally
|
||||
managed <i>flow artifacts</i> referenced by the flow definition.
|
||||
The {@link org.springframework.webflow.engine.builder.FlowServiceLocator} fulfills
|
||||
this need, acting as a facade or gateway to an external registry of
|
||||
flow artifacts (such as a Spring Bean Factory).
|
||||
</p>
|
||||
<p>
|
||||
To direct flow construction, use the
|
||||
{@link org.springframework.webflow.engine.builder.FlowAssembler}.
|
||||
You construct a Flow using a {@link org.springframework.webflow.engine.builder.FlowBuilder} implementation.
|
||||
This is done generally by using a {@link org.springframework.webflow.engine.builder.FlowAssembler}.
|
||||
This package is based on the classic GoF Builder design pattern.
|
||||
</p>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Support classes for implementing FlowBuilders.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.webflow.engine.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -26,7 +24,6 @@ import org.springframework.webflow.execution.FlowExecution;
|
||||
import org.springframework.webflow.execution.FlowExecutionFactory;
|
||||
import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
import org.springframework.webflow.execution.FlowExecutionKeyFactory;
|
||||
import org.springframework.webflow.util.RandomGuidUidGenerator;
|
||||
|
||||
/**
|
||||
* A factory for instances of the {@link FlowExecutionImpl default flow execution} implementation.
|
||||
@@ -39,7 +36,7 @@ public class FlowExecutionImplFactory extends FlowExecutionImplServicesConfigure
|
||||
/**
|
||||
* The factory used to assign keys to flow executions that need to be persisted.
|
||||
*/
|
||||
private FlowExecutionKeyFactory executionKeyFactory = new RandomFlowExecutionKeyFactory();
|
||||
private FlowExecutionKeyFactory executionKeyFactory = new SimpleFlowExecutionKeyFactory();
|
||||
|
||||
/**
|
||||
* Sets the strategy for generating flow execution keys for persistent flow executions.
|
||||
@@ -60,13 +57,19 @@ public class FlowExecutionImplFactory extends FlowExecutionImplServicesConfigure
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates random flow execution keys.
|
||||
* Simple key factory suitable for standalone usage and testing. Not expected to be used in a web environment.
|
||||
*/
|
||||
private static class RandomFlowExecutionKeyFactory implements FlowExecutionKeyFactory {
|
||||
private RandomGuidUidGenerator idGenerator = new RandomGuidUidGenerator();
|
||||
private static class SimpleFlowExecutionKeyFactory implements FlowExecutionKeyFactory {
|
||||
|
||||
private int sequence;
|
||||
|
||||
public FlowExecutionKey getKey(FlowExecution execution) {
|
||||
return new SimpleFlowExecutionKey(idGenerator.generateUid());
|
||||
if (execution.getKey() == null) {
|
||||
return new SimpleFlowExecutionKey(nextSequence());
|
||||
} else {
|
||||
// keep the same key
|
||||
return execution.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllFlowExecutionSnapshots(FlowExecution execution) {
|
||||
@@ -78,27 +81,32 @@ public class FlowExecutionImplFactory extends FlowExecutionImplServicesConfigure
|
||||
public void updateFlowExecutionSnapshot(FlowExecution execution) {
|
||||
}
|
||||
|
||||
private static class SimpleFlowExecutionKey extends FlowExecutionKey {
|
||||
private Serializable value;
|
||||
private synchronized int nextSequence() {
|
||||
return ++sequence;
|
||||
}
|
||||
|
||||
public SimpleFlowExecutionKey(Serializable value) {
|
||||
private static class SimpleFlowExecutionKey extends FlowExecutionKey {
|
||||
|
||||
private int value;
|
||||
|
||||
public SimpleFlowExecutionKey(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof SimpleFlowExecutionKey)) {
|
||||
SimpleFlowExecutionKey key = (SimpleFlowExecutionKey) o;
|
||||
return this.value.equals(key.value);
|
||||
return value == key.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.value.hashCode();
|
||||
return value * 29;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
return String.valueOf(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The implementation of Spring Web Flow's flow execution machine.
|
||||
The implementation of Spring Web Flow's flow execution engine, based on finite-state machine.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The FlowModelBuilder subsystem for building FlowModels, a configuration model for a Flow instance.
|
||||
</p>
|
||||
<p>
|
||||
You construct a FlowModel using a {@link org.springframework.webflow.engine.model.builder.FlowModelBuilder}.
|
||||
Implementations typically engineer a FlowModel from some external resource such as a file or database.
|
||||
This package is based on the classic GoF Builder design pattern.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Defines the XmlFlowModelBuilder, for building FlowModels from XML-based resources.
|
||||
</p>
|
||||
<p>
|
||||
This package also contains the definition of the XML-based flow definition language,
|
||||
defined within spring-webflow-2.0.xsd. See this schema for a detailed description of language elements.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Defines a configuration model for Flow instances.
|
||||
</p>
|
||||
<p>
|
||||
A FlowModel is a generic Java-based configuration model of a Flow, independent of any
|
||||
external flow representation such as an XML file. Flow Models can be merged together to
|
||||
facilitate reuse between flows that share a common structure.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The registry subsystem for managing collections of flow models.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The implementation of the core flow definition artifacts that serve the basis of the flow execution engine.
|
||||
The implementation of the web flow execution engine.
|
||||
</p>
|
||||
<p>
|
||||
The engine implementation itself is located within the {@link org.springframework.webflow.engine.impl impl} package.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Support implementations for internal engine-specific types.
|
||||
Support implementations the engine uses internally.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -31,10 +31,22 @@ public interface FlowExecutionKeyFactory {
|
||||
*/
|
||||
public FlowExecutionKey getKey(FlowExecution execution);
|
||||
|
||||
/**
|
||||
* Update the snapshot indexed by key of the provided execution to capture the execution's current state.
|
||||
* @param execution the flow execution
|
||||
*/
|
||||
public void updateFlowExecutionSnapshot(FlowExecution execution);
|
||||
|
||||
/**
|
||||
* Remove the snapshot indexed by the key of the provided flow execution from storage.
|
||||
* @param execution the flow execution
|
||||
*/
|
||||
public void removeFlowExecutionSnapshot(FlowExecution execution);
|
||||
|
||||
/**
|
||||
* Remove all snapshots associated with the flow execution from storage.
|
||||
* @param execution the flow execution
|
||||
*/
|
||||
public void removeAllFlowExecutionSnapshots(FlowExecution execution);
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<body>
|
||||
<p>
|
||||
Supporting types often used by flow execution factory implementations. In particular, this
|
||||
package provides a number of classes facillitating the registration of flow execution
|
||||
package provides a number of classes allowing the registration of flow execution
|
||||
listeners with a flow execution during its construction by a flow execution factory.
|
||||
</p>
|
||||
</body>
|
||||
|
||||
@@ -27,18 +27,6 @@ lifecycle events.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Package Usage example:
|
||||
<pre class="code">
|
||||
// create flow execution
|
||||
FlowDefinition definition = ...
|
||||
FlowExecutionFactory factory = ...
|
||||
FlowExecution execution = factory.createFlowExecution(definition);
|
||||
|
||||
// start execution
|
||||
ExternalContext context = ...
|
||||
ViewSelection response = execution.start(null, context);
|
||||
</pre>
|
||||
<p>
|
||||
This package depends on the definition package.
|
||||
</p>
|
||||
</body>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Support for repositories that take flow execution continuation snapshots.
|
||||
Support for repositories that take flow execution snapshots to support backtracking.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The flow execution repository subsystem for saving, and restoring managed flow executions.
|
||||
The flow execution repository subsystem for saving and restoring managed flow executions.
|
||||
</p>
|
||||
<p>
|
||||
The central concept defined by this package is the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Expression language integration. Contains Web Flow specific expression parsers.
|
||||
Expression language integration. Contains Web Flow specific ExpressionParser implementations.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
The integration between Web Flow and Spring Portlet MVC, Spring's portlet application platform.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Support for rendering Spring MVC-based Views within Web Flow.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,7 +6,7 @@ Support for testing flows and their associated artifacts.
|
||||
<p>
|
||||
When you want to unit test one of your flows the
|
||||
{@link org.springframework.webflow.test.execution.AbstractFlowExecutionTests}
|
||||
and associated subclasses provide a base you can extend.
|
||||
and its associated subclasses provide a base you can extend.
|
||||
</p>
|
||||
<p>
|
||||
When unit testing flow artifacts such as actions in isolation, the
|
||||
@@ -21,4 +21,4 @@ Fowler's</a> reasoning. These classes are called <i>Mock</i>s to be consistent w
|
||||
convention in the rest of the Spring framework (e.g. MockHttpServletRequest, ...).
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
A migration tool to convert Web Flow version 1 flow definitions to the version 2 format.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,419 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Encodes and decodes to and from Base64 notation.
|
||||
* <p>
|
||||
* Based on Base64 encoder and decoder version 2.2.1 written by Robert Harder (<a
|
||||
* href="http://iharder.net/base64">http://iharder.net/base64</a>). Modified by Erwin Vervaet to use the '.' character
|
||||
* as padding character when using URL safe encoding, like in the Bouncy Castle URLBase64 encoder (<a
|
||||
* href="http://www.bouncycastle.org/java.html">http://www.bouncycastle.org/java.html</a>).
|
||||
*
|
||||
* @author Robert Harder
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
public class Base64 {
|
||||
|
||||
/*
|
||||
* static data used by the encoding and decoding algorithm
|
||||
*/
|
||||
|
||||
/*
|
||||
* The equals sign (=) as a byte.
|
||||
*/
|
||||
private static final byte EQUALS_SIGN = (byte) '=';
|
||||
/* The dot (.) as a byte. */
|
||||
private static final byte DOT = (byte) '.';
|
||||
|
||||
private static final byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding
|
||||
private static final byte PADDING_CHAR_ENC = -1; // Indicates padding char in encoding
|
||||
|
||||
/* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */
|
||||
|
||||
/** The 64 valid Base64 values. */
|
||||
/* Host platform may be something funny like EBCDIC, so we hardcode these values. */
|
||||
private static final byte[] STANDARD_ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E',
|
||||
(byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
|
||||
(byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W',
|
||||
(byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
|
||||
(byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
|
||||
(byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x',
|
||||
(byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
|
||||
(byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/' };
|
||||
|
||||
/**
|
||||
* Translates a Base64 value to either its 6-bit reconstruction value or a negative number indicating some other
|
||||
* meaning.
|
||||
*/
|
||||
private static final byte[] STANDARD_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
|
||||
-5, -5, // Whitespace: Tab and Linefeed
|
||||
-9, -9, // Decimal 11 - 12
|
||||
-5, // Whitespace: Carriage Return
|
||||
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
|
||||
-9, -9, -9, -9, -9, // Decimal 27 - 31
|
||||
-5, // Whitespace: Space
|
||||
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
|
||||
62, // Plus sign at decimal 43
|
||||
-9, -9, -9, // Decimal 44 - 46
|
||||
63, // Slash at decimal 47
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
|
||||
-9, -9, -9, // Decimal 58 - 60
|
||||
-1, // Equals sign at decimal 61
|
||||
-9, -9, -9, // Decimal 62 - 64
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
|
||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
|
||||
-9, -9, -9, -9, -9, -9, // Decimal 91 - 96
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
|
||||
-9, -9, -9, -9 // Decimal 123 - 126
|
||||
};
|
||||
|
||||
/* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */
|
||||
|
||||
/**
|
||||
* Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: <a
|
||||
* href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>. Notice that the last two
|
||||
* bytes become "hyphen" and "underscore" instead of "plus" and "slash."
|
||||
*/
|
||||
private static final byte[] URL_SAFE_ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E',
|
||||
(byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
|
||||
(byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W',
|
||||
(byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
|
||||
(byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
|
||||
(byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x',
|
||||
(byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
|
||||
(byte) '7', (byte) '8', (byte) '9', (byte) '-', (byte) '_' };
|
||||
|
||||
/**
|
||||
* Used in decoding URL- and Filename-safe dialects of Base64.
|
||||
*/
|
||||
private static final byte[] URL_SAFE_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
|
||||
-5, -5, // Whitespace: Tab and Linefeed
|
||||
-9, -9, // Decimal 11 - 12
|
||||
-5, // Whitespace: Carriage Return
|
||||
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
|
||||
-9, -9, -9, -9, -9, // Decimal 27 - 31
|
||||
-5, // Whitespace: Space
|
||||
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
|
||||
-9, // Plus sign at decimal 43
|
||||
-9, // Decimal 44
|
||||
62, // Minus sign at decimal 45
|
||||
-1, // Dot at decimal 46
|
||||
-9, // Slash at decimal 47
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
|
||||
-9, -9, -9, // Decimal 58 - 60
|
||||
-9, // Equals sign at decimal 61
|
||||
-9, -9, -9, // Decimal 62 - 64
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
|
||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
|
||||
-9, -9, -9, -9, // Decimal 91 - 94
|
||||
63, // Underscore at decimal 95
|
||||
-9, // Decimal 96
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
|
||||
-9, -9, -9, -9 // Decimal 123 - 126
|
||||
};
|
||||
|
||||
// instance members
|
||||
|
||||
/**
|
||||
* Encode using Base64-like encoding that is URL- and Filename-safe as described in Section 4 of RFC3548: <a
|
||||
* href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
|
||||
*/
|
||||
private boolean urlSafe;
|
||||
|
||||
private byte[] ALPHABET;
|
||||
private byte[] DECODABET;
|
||||
private byte PADDING_CHAR;
|
||||
|
||||
/**
|
||||
* Create a new Base64 encoder and decoder using the standard Base64 alphabet. Note that the resulting encoded
|
||||
* strings are not <i>URL-safe</i>: they will can contain characters that are subject to URL encoding.
|
||||
*/
|
||||
public Base64() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Base64 encoder and decoder.
|
||||
* <p>
|
||||
* Allows Base64-like encoding that is URL- and Filename-safe as described in Section 4 of RFC3548: <a
|
||||
* href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>. When URL-safe encoding
|
||||
* is used, the standard "=" Base64 padding character is replaced with the '.' character.
|
||||
* <p>
|
||||
* It is important to note that data encoded this way is <em>not</em> officially valid Base64, or at the very
|
||||
* least should not be called Base64 without also specifying that is was encoded using the URL- and Filename-safe
|
||||
* dialect
|
||||
*
|
||||
* @param urlSafe if true, URL safe encoding and decoding will be used
|
||||
*/
|
||||
public Base64(boolean urlSafe) {
|
||||
this.urlSafe = urlSafe;
|
||||
if (urlSafe) {
|
||||
ALPHABET = URL_SAFE_ALPHABET;
|
||||
DECODABET = URL_SAFE_DECODABET;
|
||||
PADDING_CHAR = DOT;
|
||||
} else {
|
||||
ALPHABET = STANDARD_ALPHABET;
|
||||
DECODABET = STANDARD_DECODABET;
|
||||
PADDING_CHAR = EQUALS_SIGN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not this coder is using Base64-like encoding that is URL- and Filename-safe as described in
|
||||
* Section 4 of RFC3548: <a href="http://www.faqs.org/rfcs/rfc3548.html">http://www.faqs.org/rfcs/rfc3548.html</a>.
|
||||
* When URL-safe encoding is used, the standard "=" Base64 padding character is replaced with the '.' character.
|
||||
* <p>
|
||||
* It is important to note that data encoded this way is <em>not</em> officially valid Base64, or at the very
|
||||
* least should not be called Base64 without also specifying that is was encoded using the URL- and Filename-safe
|
||||
* dialect.
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean isUrlSafe() {
|
||||
return urlSafe;
|
||||
}
|
||||
|
||||
/* ******** E N C O D I N G M E T H O D S ******** */
|
||||
|
||||
/**
|
||||
* Encodes up to three bytes of the array <var>source</var> and writes the resulting four Base64 bytes to
|
||||
* <var>destination</var>. The source and destination arrays can be manipulated anywhere along their length by
|
||||
* specifying <var>srcOffset</var> and <var>destOffset</var>. This method does not check to make sure your arrays
|
||||
* are large enough to accomodate <var>srcOffset</var> + 3 for the <var>source</var> array or <var>destOffset</var> +
|
||||
* 4 for the <var>destination</var> array. The actual number of significant bytes in your array is given by
|
||||
* <var>numSigBytes</var>.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is the lowest level of the encoding methods with all possible parameters.
|
||||
* </p>
|
||||
* @param source the array to convert
|
||||
* @param srcOffset the index where conversion begins
|
||||
* @param numSigBytes the number of significant bytes in your array
|
||||
* @param destination the array to hold the conversion
|
||||
* @param destOffset the index where output will be put
|
||||
* @return the <var>destination</var> array
|
||||
*/
|
||||
private byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset) {
|
||||
// 1 2 3
|
||||
// 01234567890123456789012345678901 Bit position
|
||||
// --------000000001111111122222222 Array position from threeBytes
|
||||
// --------| || || || | Six bit groups to index ALPHABET
|
||||
// >>18 >>12 >> 6 >> 0 Right shift necessary
|
||||
// 0x3f 0x3f 0x3f Additional AND
|
||||
|
||||
// Create buffer with zero-padding if there are only one or two
|
||||
// significant bytes passed in the array.
|
||||
// We have to shift left 24 in order to flush out the 1's that appear
|
||||
// when Java treats a value as negative that is cast from a byte to an int.
|
||||
int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
|
||||
| (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
|
||||
| (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
|
||||
|
||||
switch (numSigBytes) {
|
||||
case 3:
|
||||
destination[destOffset] = ALPHABET[(inBuff >>> 18)];
|
||||
destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
|
||||
destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
|
||||
destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
|
||||
return destination;
|
||||
|
||||
case 2:
|
||||
destination[destOffset] = ALPHABET[(inBuff >>> 18)];
|
||||
destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
|
||||
destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
|
||||
destination[destOffset + 3] = PADDING_CHAR;
|
||||
return destination;
|
||||
|
||||
case 1:
|
||||
destination[destOffset] = ALPHABET[(inBuff >>> 18)];
|
||||
destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
|
||||
destination[destOffset + 2] = PADDING_CHAR;
|
||||
destination[destOffset + 3] = PADDING_CHAR;
|
||||
return destination;
|
||||
|
||||
default:
|
||||
return destination;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a byte array into Base64 notation.
|
||||
* @param source the data to convert
|
||||
* @param off offset in array where conversion should begin
|
||||
* @param len length of data to convert
|
||||
* @return the encoded data
|
||||
*/
|
||||
public final byte[] encode(byte[] source, int off, int len) {
|
||||
int len43 = len * 4 / 3;
|
||||
byte[] outBuff = new byte[(len43) // main 4:3
|
||||
+ ((len % 3) > 0 ? 4 : 0)]; // account for padding
|
||||
int d = 0;
|
||||
int e = 0;
|
||||
int len2 = len - 2;
|
||||
int lineLength = 0;
|
||||
for (; d < len2; d += 3, e += 4) {
|
||||
encode3to4(source, d + off, 3, outBuff, e);
|
||||
|
||||
lineLength += 4;
|
||||
} // end for: each piece of array
|
||||
|
||||
if (d < len) {
|
||||
encode3to4(source, d + off, len - d, outBuff, e);
|
||||
e += 4;
|
||||
} // end if: some padding needed
|
||||
|
||||
byte[] out = new byte[e];
|
||||
System.arraycopy(outBuff, 0, out, 0, e);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a byte array into Base64 notation.
|
||||
* @param source the data to encode
|
||||
* @return the encoded data
|
||||
*/
|
||||
public final byte[] encode(byte[] source) {
|
||||
return encode(source, 0, source.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a byte array into Base64 notation. The resulting string will be created using the platform default
|
||||
* encoding.
|
||||
* @param source the source data to encode
|
||||
* @return the encoded data
|
||||
*/
|
||||
public final String encodeToString(byte[] source) {
|
||||
return new String(encode(source));
|
||||
}
|
||||
|
||||
/* ******** D E C O D I N G M E T H O D S ******** */
|
||||
|
||||
/**
|
||||
* Decodes four bytes from array <var>source</var> and writes the resulting bytes (up to three of them) to
|
||||
* <var>destination</var>. The source and destination arrays can be manipulated anywhere along their length by
|
||||
* specifying <var>srcOffset</var> and <var>destOffset</var>. This method does not check to make sure your arrays
|
||||
* are large enough to accomodate <var>srcOffset</var> + 4 for the <var>source</var> array or <var>destOffset</var> +
|
||||
* 3 for the <var>destination</var> array. This method returns the actual number of bytes that were converted from
|
||||
* the Base64 encoding.
|
||||
* <p>
|
||||
* This is the lowest level of the decoding methods with all possible parameters.
|
||||
* </p>
|
||||
* @param source the array to convert
|
||||
* @param srcOffset the index where conversion begins
|
||||
* @param destination the array to hold the conversion
|
||||
* @param destOffset the index where output will be put
|
||||
* @return the number of decoded bytes converted
|
||||
*/
|
||||
private final int decode4to3(byte[] source, int srcOffset, byte[] destination, int destOffset) {
|
||||
// Example: Dk== or Dk..
|
||||
if (source[srcOffset + 2] == PADDING_CHAR) {
|
||||
int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
|
||||
| ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
|
||||
|
||||
destination[destOffset] = (byte) (outBuff >>> 16);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Example: DkL= or DkL.
|
||||
else if (source[srcOffset + 3] == PADDING_CHAR) {
|
||||
int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
|
||||
| ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
|
||||
| ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
|
||||
|
||||
destination[destOffset] = (byte) (outBuff >>> 16);
|
||||
destination[destOffset + 1] = (byte) (outBuff >>> 8);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Example: DkLE
|
||||
else {
|
||||
int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
|
||||
| ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
|
||||
| ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) | ((DECODABET[source[srcOffset + 3]] & 0xFF));
|
||||
|
||||
destination[destOffset] = (byte) (outBuff >> 16);
|
||||
destination[destOffset + 1] = (byte) (outBuff >> 8);
|
||||
destination[destOffset + 2] = (byte) (outBuff);
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Very low-level access to decoding ASCII characters in the form of a byte array.
|
||||
* @param source the Base64 encoded data
|
||||
* @param off the offset of where to begin decoding
|
||||
* @param len the length of characters to decode
|
||||
* @return decoded data
|
||||
*/
|
||||
public final byte[] decode(byte[] source, int off, int len) {
|
||||
int len34 = len * 3 / 4;
|
||||
byte[] outBuff = new byte[len34]; // upper limit on size of output
|
||||
int outBuffPosn = 0;
|
||||
|
||||
byte[] b4 = new byte[4];
|
||||
int b4Posn = 0;
|
||||
int i = 0;
|
||||
byte sbiCrop = 0;
|
||||
byte sbiDecode = 0;
|
||||
for (i = off; i < off + len; i++) {
|
||||
sbiCrop = (byte) (source[i] & 0x7f); // only the low seven bits
|
||||
sbiDecode = DECODABET[sbiCrop];
|
||||
|
||||
if (sbiDecode >= WHITE_SPACE_ENC) { // white space, equals sign or better
|
||||
if (sbiDecode >= PADDING_CHAR_ENC) {
|
||||
b4[b4Posn++] = sbiCrop;
|
||||
if (b4Posn > 3) {
|
||||
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn);
|
||||
b4Posn = 0;
|
||||
|
||||
// if that was the padding char, break out of 'for' loop
|
||||
if (sbiCrop == PADDING_CHAR) {
|
||||
break;
|
||||
}
|
||||
} // end if: quartet built
|
||||
} // end if: equals sign or better
|
||||
} // end if: white space, equals sign or better
|
||||
else {
|
||||
// discard
|
||||
}
|
||||
} // each input character
|
||||
|
||||
byte[] out = new byte[outBuffPosn];
|
||||
System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes data from Base64 notation.
|
||||
* @param source the source data
|
||||
* @return the decoded data
|
||||
*/
|
||||
public final byte[] decode(byte[] source) {
|
||||
return decode(source, 0, source.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes data from Base64 notation. Uses the platform default character set to obtain bytes from given string.
|
||||
* @param s the string to decode
|
||||
* @return the decoded data
|
||||
*/
|
||||
public final byte[] decodeFromString(String s) {
|
||||
return decode(s.getBytes());
|
||||
}
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* RandomGUID from http://www.javaexchange.com/aboutRandomGUID.html
|
||||
* @version 1.2.1 11/05/02 @author Marc A. Mnich
|
||||
*
|
||||
* From www.JavaExchange.com, Open Software licensing
|
||||
*
|
||||
* 11/05/02 -- Performance enhancement from Mike Dubman. Moved InetAddr.getLocal to static block. Mike has measured a 10
|
||||
* fold improvement in run time. 01/29/02 -- Bug fix: Improper seeding of nonsecure Random object caused duplicate GUIDs
|
||||
* to be produced. Random object is now only created once per JVM. 01/19/02 -- Modified random seeding and added new
|
||||
* constructor to allow secure random feature. 01/14/02 -- Added random function seeding with JVM run time
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Globally unique identifier generator.
|
||||
* <p>
|
||||
* In the multitude of java GUID generators, I found none that guaranteed randomness. GUIDs are guaranteed to be
|
||||
* globally unique by using ethernet MACs, IP addresses, time elements, and sequential numbers. GUIDs are not expected
|
||||
* to be random and most often are easy/possible to guess given a sample from a given generator. SQL Server, for example
|
||||
* generates GUID that are unique but sequencial within a given instance.
|
||||
* <p>
|
||||
* GUIDs can be used as security devices to hide things such as files within a filesystem where listings are unavailable
|
||||
* (e.g. files that are served up from a Web server with indexing turned off). This may be desireable in cases where
|
||||
* standard authentication is not appropriate. In this scenario, the RandomGuids are used as directories. Another
|
||||
* example is the use of GUIDs for primary keys in a database where you want to ensure that the keys are secret. Random
|
||||
* GUIDs can then be used in a URL to prevent hackers (or users) from accessing records by guessing or simply by
|
||||
* incrementing sequential numbers.
|
||||
* <p>
|
||||
* There are many other possiblities of using GUIDs in the realm of security and encryption where the element of
|
||||
* randomness is important. This class was written for these purposes but can also be used as a general purpose GUID
|
||||
* generator as well.
|
||||
* <p>
|
||||
* RandomGuid generates truly random GUIDs by using the system's IP address (name/IP), system time in milliseconds (as
|
||||
* an integer), and a very large random number joined together in a single String that is passed through an MD5 hash.
|
||||
* The IP address and system time make the MD5 seed globally unique and the random number guarantees that the generated
|
||||
* GUIDs will have no discernable pattern and cannot be guessed given any number of previously generated GUIDs. It is
|
||||
* generally not possible to access the seed information (IP, time, random number) from the resulting GUIDs as the MD5
|
||||
* hash algorithm provides one way encryption.
|
||||
* <p>
|
||||
* <b>Security of RandomGuid</b>: RandomGuid can be called one of two ways -- with the basic java Random number
|
||||
* generator or a cryptographically strong random generator (SecureRandom). The choice is offered because the secure
|
||||
* random generator takes about 3.5 times longer to generate its random numbers and this performance hit may not be
|
||||
* worth the added security especially considering the basic generator is seeded with a cryptographically strong random
|
||||
* seed.
|
||||
* <p>
|
||||
* Seeding the basic generator in this way effectively decouples the random numbers from the time component making it
|
||||
* virtually impossible to predict the random number component even if one had absolute knowledge of the System time.
|
||||
* Thanks to Ashutosh Narhari for the suggestion of using the static method to prime the basic random generator.
|
||||
* <p>
|
||||
* Using the secure random option, this class complies with the statistical random number generator tests specified in
|
||||
* FIPS 140-2, Security Requirements for Cryptographic Modules, secition 4.9.1.
|
||||
* <p>
|
||||
* I converted all the pieces of the seed to a String before handing it over to the MD5 hash so that you could print it
|
||||
* out to make sure it contains the data you expect to see and to give a nice warm fuzzy. If you need better
|
||||
* performance, you may want to stick to byte[] arrays.
|
||||
* <p>
|
||||
* I believe that it is important that the algorithm for generating random GUIDs be open for inspection and
|
||||
* modification. This class is free for all uses.
|
||||
*
|
||||
* @version 1.2.1 11/05/02
|
||||
* @author Marc A. Mnich
|
||||
*/
|
||||
public class RandomGuid {
|
||||
|
||||
private static Random random;
|
||||
|
||||
private static SecureRandom secureRandom;
|
||||
|
||||
private static String id;
|
||||
|
||||
private String guid;
|
||||
|
||||
/*
|
||||
* Static block to take care of one time secureRandom seed. It takes a few seconds to initialize SecureRandom. You
|
||||
* might want to consider removing this static block or replacing it with a "time since first loaded" seed to reduce
|
||||
* this time. This block will run only once per JVM instance.
|
||||
*/
|
||||
static {
|
||||
secureRandom = new SecureRandom();
|
||||
long secureInitializer = secureRandom.nextLong();
|
||||
random = new Random(secureInitializer);
|
||||
try {
|
||||
id = InetAddress.getLocalHost().toString();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor. With no specification of security option, this constructor defaults to lower security, high
|
||||
* performance.
|
||||
*/
|
||||
public RandomGuid() {
|
||||
getRandomGuid(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with security option. Setting secure true enables each random number generated to be
|
||||
* cryptographically strong. Secure false defaults to the standard Random function seeded with a single
|
||||
* cryptographically strong random number.
|
||||
*/
|
||||
public RandomGuid(boolean secure) {
|
||||
getRandomGuid(secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to generate the random GUID.
|
||||
*/
|
||||
private void getRandomGuid(boolean secure) {
|
||||
MessageDigest md5 = null;
|
||||
StringBuffer sbValueBeforeMD5 = new StringBuffer();
|
||||
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
long rand = 0;
|
||||
|
||||
if (secure) {
|
||||
rand = secureRandom.nextLong();
|
||||
} else {
|
||||
rand = random.nextLong();
|
||||
}
|
||||
|
||||
// This StringBuffer can be a long as you need; the MD5
|
||||
// hash will always return 128 bits. You can change
|
||||
// the seed to include anything you want here.
|
||||
// You could even stream a file through the MD5 making
|
||||
// the odds of guessing it at least as great as that
|
||||
// of guessing the contents of the file!
|
||||
sbValueBeforeMD5.append(id);
|
||||
sbValueBeforeMD5.append(":");
|
||||
sbValueBeforeMD5.append(Long.toString(time));
|
||||
sbValueBeforeMD5.append(":");
|
||||
sbValueBeforeMD5.append(Long.toString(rand));
|
||||
|
||||
String valueBeforeMD5 = sbValueBeforeMD5.toString();
|
||||
md5.update(valueBeforeMD5.getBytes());
|
||||
|
||||
byte[] array = md5.digest();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int j = 0; j < array.length; ++j) {
|
||||
int b = array[j] & 0xFF;
|
||||
if (b < 0x10)
|
||||
sb.append('0');
|
||||
sb.append(Integer.toHexString(b));
|
||||
}
|
||||
guid = sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to the standard format for GUID (Useful for SQL Server UniqueIdentifiers, etc). Example:
|
||||
* "C2FEEEAC-CFCD-11D1-8B05-00600806D9B6".
|
||||
*/
|
||||
public String toString() {
|
||||
String raw = guid.toUpperCase();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(raw.substring(0, 8));
|
||||
sb.append("-");
|
||||
sb.append(raw.substring(8, 12));
|
||||
sb.append("-");
|
||||
sb.append(raw.substring(12, 16));
|
||||
sb.append("-");
|
||||
sb.append(raw.substring(16, 20));
|
||||
sb.append("-");
|
||||
sb.append(raw.substring(20));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* 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.io.Serializable;
|
||||
|
||||
/**
|
||||
* A key generator that uses the RandomGuid support class. The default implementation used by the webflow system.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class RandomGuidUidGenerator implements UidGenerator, Serializable {
|
||||
|
||||
/**
|
||||
* Should the random GUID generated be secure?
|
||||
*/
|
||||
private boolean secure;
|
||||
|
||||
/**
|
||||
* Returns whether or not the generated random numbers are <i>secure</i>, meaning cryptographically strong.
|
||||
*/
|
||||
public boolean isSecure() {
|
||||
return secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not the generated random numbers should be <i>secure</i>. If set to true, generated GUIDs are
|
||||
* cryptographically strong.
|
||||
*/
|
||||
public void setSecure(boolean secure) {
|
||||
this.secure = secure;
|
||||
}
|
||||
|
||||
public Serializable generateUid() {
|
||||
return new RandomGuid(secure).toString();
|
||||
}
|
||||
|
||||
public Serializable parseUid(String encodedUid) {
|
||||
return encodedUid;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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 org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Simple interface for all objects (typically flow builders) that hold on to a resource defining a flow (e.g. an XML
|
||||
* file). Provides a way to access information about the underlying resource like the last modified date.
|
||||
*
|
||||
* @see org.springframework.webflow.engine.builder.FlowBuilder
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface ResourceHolder {
|
||||
|
||||
/**
|
||||
* Returns the flow definition resource held by this holder.
|
||||
*/
|
||||
public Resource getResource();
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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.io.Serializable;
|
||||
|
||||
/**
|
||||
* A strategy for generating ids for uniquely identifying execution artifacts such as FlowExecutions and any other
|
||||
* uniquely identified flow artifact.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface UidGenerator {
|
||||
|
||||
/**
|
||||
* Generate a new unique id.
|
||||
* @return a serializable id, guaranteed to be unique in some context
|
||||
*/
|
||||
public Serializable generateUid();
|
||||
|
||||
/**
|
||||
* Convert the string-encoded uid into its original object form.
|
||||
* @param encodedUid the string encoded uid
|
||||
* @return the converted uid
|
||||
*/
|
||||
public Serializable parseUid(String encodedUid);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
General purpose utility classes used internally by the Spring Web Flow system.
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,7 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.util;
|
||||
package org.springframework.webflow.action;
|
||||
|
||||
import org.springframework.webflow.action.DispatchMethodInvoker;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.webflow.action;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.webflow.action.DispatchMethodInvoker.MethodLookupException;
|
||||
import org.springframework.webflow.action.MultiAction.MethodResolver;
|
||||
import org.springframework.webflow.engine.AnnotatedAction;
|
||||
import org.springframework.webflow.engine.StubViewFactory;
|
||||
@@ -24,7 +25,6 @@ import org.springframework.webflow.engine.ViewState;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.test.MockFlowSession;
|
||||
import org.springframework.webflow.test.MockRequestContext;
|
||||
import org.springframework.webflow.util.DispatchMethodInvoker.MethodLookupException;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MultiAction}.
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.springframework.webflow.engine.EndState;
|
||||
import org.springframework.webflow.engine.Flow;
|
||||
import org.springframework.webflow.engine.builder.support.AbstractFlowBuilder;
|
||||
import org.springframework.webflow.test.MockFlowBuilderContext;
|
||||
import org.springframework.webflow.util.ResourceHolder;
|
||||
|
||||
public class DefaultFlowHolderTests extends TestCase {
|
||||
private DefaultFlowHolder holder;
|
||||
@@ -47,7 +46,7 @@ public class DefaultFlowHolderTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
public class ChangeDetectableFlowBuilder extends SimpleFlowBuilder implements ResourceHolder {
|
||||
public class ChangeDetectableFlowBuilder extends SimpleFlowBuilder {
|
||||
private FileSystemResource resource = new FileSystemResource("file.txt");
|
||||
|
||||
public Resource getResource() {
|
||||
|
||||
@@ -2,14 +2,12 @@ package org.springframework.webflow.engine.model.registry;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.webflow.engine.model.AbstractStateModel;
|
||||
import org.springframework.webflow.engine.model.EndStateModel;
|
||||
import org.springframework.webflow.engine.model.FlowModel;
|
||||
import org.springframework.webflow.engine.model.builder.FlowModelBuilder;
|
||||
import org.springframework.webflow.engine.model.builder.FlowModelBuilderException;
|
||||
import org.springframework.webflow.util.ResourceHolder;
|
||||
|
||||
public class DefaultFlowModelHolderTests extends TestCase {
|
||||
private DefaultFlowModelHolder holder;
|
||||
@@ -67,13 +65,4 @@ public class DefaultFlowModelHolderTests extends TestCase {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ChangeDetectableFlowBuilder extends SimpleFlowBuilder implements ResourceHolder {
|
||||
private FileSystemResource resource = new FileSystemResource("file.txt");
|
||||
|
||||
public Resource getResource() {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,554 +0,0 @@
|
||||
/*
|
||||
* 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.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Test case for {@link Base64}. Based on Base64Test from Jakarta Commons Codec 1.3.
|
||||
*
|
||||
* @author Erwin Vervaet
|
||||
*/
|
||||
public class Base64Tests extends TestCase {
|
||||
|
||||
private Random random = new Random();
|
||||
|
||||
public Random getRandom() {
|
||||
return this.random;
|
||||
}
|
||||
|
||||
public void testBase64() {
|
||||
assertEquals("SGVsbG8gV29ybGQ=", new Base64().encodeToString("Hello World".getBytes()));
|
||||
assertEquals("SGVsbG8gV29ybGQ.", new Base64(true).encodeToString("Hello World".getBytes()));
|
||||
}
|
||||
|
||||
public void testDecodePadMarkerIndex2() {
|
||||
assertEquals("A", new String(new Base64().decodeFromString("QQ==")));
|
||||
assertEquals("A", new String(new Base64(true).decodeFromString("QQ..")));
|
||||
}
|
||||
|
||||
public void testDecodePadMarkerIndex3() {
|
||||
assertEquals("AA", new String(new Base64().decodeFromString("QUE=")));
|
||||
assertEquals("AAA", new String(new Base64().decodeFromString("QUFB")));
|
||||
assertEquals("AA", new String(new Base64(true).decodeFromString("QUE.")));
|
||||
assertEquals("AAA", new String(new Base64(true).decodeFromString("QUFB")));
|
||||
}
|
||||
|
||||
public void testEncodeEmptyString() {
|
||||
assertEquals("", new Base64().encodeToString("".getBytes()));
|
||||
}
|
||||
|
||||
public void testDecodeEmptyString() {
|
||||
assertEquals("", new String(new Base64().decodeFromString("")));
|
||||
}
|
||||
|
||||
// encode/decode random arrays from size 0 to size 11
|
||||
public void testEncodeDecodeSmall() {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
byte[] data = new byte[i];
|
||||
this.getRandom().nextBytes(data);
|
||||
byte[] enc = new Base64().encode(data);
|
||||
byte[] data2 = new Base64().decode(enc);
|
||||
assertTrue(Arrays.equals(data, data2));
|
||||
}
|
||||
}
|
||||
|
||||
// encode/decode a large random array
|
||||
public void testEncodeDecodeRandom() {
|
||||
for (int i = 1; i < 5; i++) {
|
||||
byte[] data = new byte[this.getRandom().nextInt(10000) + 1];
|
||||
this.getRandom().nextBytes(data);
|
||||
byte[] enc = new Base64().encode(data);
|
||||
byte[] data2 = new Base64().decode(enc);
|
||||
assertTrue(Arrays.equals(data, data2));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSingletons() {
|
||||
assertEquals("AA==", new String(new Base64().encode(new byte[] { (byte) 0 })));
|
||||
assertEquals("AQ==", new String(new Base64().encode(new byte[] { (byte) 1 })));
|
||||
assertEquals("Ag==", new String(new Base64().encode(new byte[] { (byte) 2 })));
|
||||
assertEquals("Aw==", new String(new Base64().encode(new byte[] { (byte) 3 })));
|
||||
assertEquals("BA==", new String(new Base64().encode(new byte[] { (byte) 4 })));
|
||||
assertEquals("BQ==", new String(new Base64().encode(new byte[] { (byte) 5 })));
|
||||
assertEquals("Bg==", new String(new Base64().encode(new byte[] { (byte) 6 })));
|
||||
assertEquals("Bw==", new String(new Base64().encode(new byte[] { (byte) 7 })));
|
||||
assertEquals("CA==", new String(new Base64().encode(new byte[] { (byte) 8 })));
|
||||
assertEquals("CQ==", new String(new Base64().encode(new byte[] { (byte) 9 })));
|
||||
assertEquals("Cg==", new String(new Base64().encode(new byte[] { (byte) 10 })));
|
||||
assertEquals("Cw==", new String(new Base64().encode(new byte[] { (byte) 11 })));
|
||||
assertEquals("DA==", new String(new Base64().encode(new byte[] { (byte) 12 })));
|
||||
assertEquals("DQ==", new String(new Base64().encode(new byte[] { (byte) 13 })));
|
||||
assertEquals("Dg==", new String(new Base64().encode(new byte[] { (byte) 14 })));
|
||||
assertEquals("Dw==", new String(new Base64().encode(new byte[] { (byte) 15 })));
|
||||
assertEquals("EA==", new String(new Base64().encode(new byte[] { (byte) 16 })));
|
||||
assertEquals("EQ==", new String(new Base64().encode(new byte[] { (byte) 17 })));
|
||||
assertEquals("Eg==", new String(new Base64().encode(new byte[] { (byte) 18 })));
|
||||
assertEquals("Ew==", new String(new Base64().encode(new byte[] { (byte) 19 })));
|
||||
assertEquals("FA==", new String(new Base64().encode(new byte[] { (byte) 20 })));
|
||||
assertEquals("FQ==", new String(new Base64().encode(new byte[] { (byte) 21 })));
|
||||
assertEquals("Fg==", new String(new Base64().encode(new byte[] { (byte) 22 })));
|
||||
assertEquals("Fw==", new String(new Base64().encode(new byte[] { (byte) 23 })));
|
||||
assertEquals("GA==", new String(new Base64().encode(new byte[] { (byte) 24 })));
|
||||
assertEquals("GQ==", new String(new Base64().encode(new byte[] { (byte) 25 })));
|
||||
assertEquals("Gg==", new String(new Base64().encode(new byte[] { (byte) 26 })));
|
||||
assertEquals("Gw==", new String(new Base64().encode(new byte[] { (byte) 27 })));
|
||||
assertEquals("HA==", new String(new Base64().encode(new byte[] { (byte) 28 })));
|
||||
assertEquals("HQ==", new String(new Base64().encode(new byte[] { (byte) 29 })));
|
||||
assertEquals("Hg==", new String(new Base64().encode(new byte[] { (byte) 30 })));
|
||||
assertEquals("Hw==", new String(new Base64().encode(new byte[] { (byte) 31 })));
|
||||
assertEquals("IA==", new String(new Base64().encode(new byte[] { (byte) 32 })));
|
||||
assertEquals("IQ==", new String(new Base64().encode(new byte[] { (byte) 33 })));
|
||||
assertEquals("Ig==", new String(new Base64().encode(new byte[] { (byte) 34 })));
|
||||
assertEquals("Iw==", new String(new Base64().encode(new byte[] { (byte) 35 })));
|
||||
assertEquals("JA==", new String(new Base64().encode(new byte[] { (byte) 36 })));
|
||||
assertEquals("JQ==", new String(new Base64().encode(new byte[] { (byte) 37 })));
|
||||
assertEquals("Jg==", new String(new Base64().encode(new byte[] { (byte) 38 })));
|
||||
assertEquals("Jw==", new String(new Base64().encode(new byte[] { (byte) 39 })));
|
||||
assertEquals("KA==", new String(new Base64().encode(new byte[] { (byte) 40 })));
|
||||
assertEquals("KQ==", new String(new Base64().encode(new byte[] { (byte) 41 })));
|
||||
assertEquals("Kg==", new String(new Base64().encode(new byte[] { (byte) 42 })));
|
||||
assertEquals("Kw==", new String(new Base64().encode(new byte[] { (byte) 43 })));
|
||||
assertEquals("LA==", new String(new Base64().encode(new byte[] { (byte) 44 })));
|
||||
assertEquals("LQ==", new String(new Base64().encode(new byte[] { (byte) 45 })));
|
||||
assertEquals("Lg==", new String(new Base64().encode(new byte[] { (byte) 46 })));
|
||||
assertEquals("Lw==", new String(new Base64().encode(new byte[] { (byte) 47 })));
|
||||
assertEquals("MA==", new String(new Base64().encode(new byte[] { (byte) 48 })));
|
||||
assertEquals("MQ==", new String(new Base64().encode(new byte[] { (byte) 49 })));
|
||||
assertEquals("Mg==", new String(new Base64().encode(new byte[] { (byte) 50 })));
|
||||
assertEquals("Mw==", new String(new Base64().encode(new byte[] { (byte) 51 })));
|
||||
assertEquals("NA==", new String(new Base64().encode(new byte[] { (byte) 52 })));
|
||||
assertEquals("NQ==", new String(new Base64().encode(new byte[] { (byte) 53 })));
|
||||
assertEquals("Ng==", new String(new Base64().encode(new byte[] { (byte) 54 })));
|
||||
assertEquals("Nw==", new String(new Base64().encode(new byte[] { (byte) 55 })));
|
||||
assertEquals("OA==", new String(new Base64().encode(new byte[] { (byte) 56 })));
|
||||
assertEquals("OQ==", new String(new Base64().encode(new byte[] { (byte) 57 })));
|
||||
assertEquals("Og==", new String(new Base64().encode(new byte[] { (byte) 58 })));
|
||||
assertEquals("Ow==", new String(new Base64().encode(new byte[] { (byte) 59 })));
|
||||
assertEquals("PA==", new String(new Base64().encode(new byte[] { (byte) 60 })));
|
||||
assertEquals("PQ==", new String(new Base64().encode(new byte[] { (byte) 61 })));
|
||||
assertEquals("Pg==", new String(new Base64().encode(new byte[] { (byte) 62 })));
|
||||
assertEquals("Pw==", new String(new Base64().encode(new byte[] { (byte) 63 })));
|
||||
assertEquals("QA==", new String(new Base64().encode(new byte[] { (byte) 64 })));
|
||||
assertEquals("QQ==", new String(new Base64().encode(new byte[] { (byte) 65 })));
|
||||
assertEquals("Qg==", new String(new Base64().encode(new byte[] { (byte) 66 })));
|
||||
assertEquals("Qw==", new String(new Base64().encode(new byte[] { (byte) 67 })));
|
||||
assertEquals("RA==", new String(new Base64().encode(new byte[] { (byte) 68 })));
|
||||
assertEquals("RQ==", new String(new Base64().encode(new byte[] { (byte) 69 })));
|
||||
assertEquals("Rg==", new String(new Base64().encode(new byte[] { (byte) 70 })));
|
||||
assertEquals("Rw==", new String(new Base64().encode(new byte[] { (byte) 71 })));
|
||||
assertEquals("SA==", new String(new Base64().encode(new byte[] { (byte) 72 })));
|
||||
assertEquals("SQ==", new String(new Base64().encode(new byte[] { (byte) 73 })));
|
||||
assertEquals("Sg==", new String(new Base64().encode(new byte[] { (byte) 74 })));
|
||||
assertEquals("Sw==", new String(new Base64().encode(new byte[] { (byte) 75 })));
|
||||
assertEquals("TA==", new String(new Base64().encode(new byte[] { (byte) 76 })));
|
||||
assertEquals("TQ==", new String(new Base64().encode(new byte[] { (byte) 77 })));
|
||||
assertEquals("Tg==", new String(new Base64().encode(new byte[] { (byte) 78 })));
|
||||
assertEquals("Tw==", new String(new Base64().encode(new byte[] { (byte) 79 })));
|
||||
assertEquals("UA==", new String(new Base64().encode(new byte[] { (byte) 80 })));
|
||||
assertEquals("UQ==", new String(new Base64().encode(new byte[] { (byte) 81 })));
|
||||
assertEquals("Ug==", new String(new Base64().encode(new byte[] { (byte) 82 })));
|
||||
assertEquals("Uw==", new String(new Base64().encode(new byte[] { (byte) 83 })));
|
||||
assertEquals("VA==", new String(new Base64().encode(new byte[] { (byte) 84 })));
|
||||
assertEquals("VQ==", new String(new Base64().encode(new byte[] { (byte) 85 })));
|
||||
assertEquals("Vg==", new String(new Base64().encode(new byte[] { (byte) 86 })));
|
||||
assertEquals("Vw==", new String(new Base64().encode(new byte[] { (byte) 87 })));
|
||||
assertEquals("WA==", new String(new Base64().encode(new byte[] { (byte) 88 })));
|
||||
assertEquals("WQ==", new String(new Base64().encode(new byte[] { (byte) 89 })));
|
||||
assertEquals("Wg==", new String(new Base64().encode(new byte[] { (byte) 90 })));
|
||||
assertEquals("Ww==", new String(new Base64().encode(new byte[] { (byte) 91 })));
|
||||
assertEquals("XA==", new String(new Base64().encode(new byte[] { (byte) 92 })));
|
||||
assertEquals("XQ==", new String(new Base64().encode(new byte[] { (byte) 93 })));
|
||||
assertEquals("Xg==", new String(new Base64().encode(new byte[] { (byte) 94 })));
|
||||
assertEquals("Xw==", new String(new Base64().encode(new byte[] { (byte) 95 })));
|
||||
assertEquals("YA==", new String(new Base64().encode(new byte[] { (byte) 96 })));
|
||||
assertEquals("YQ==", new String(new Base64().encode(new byte[] { (byte) 97 })));
|
||||
assertEquals("Yg==", new String(new Base64().encode(new byte[] { (byte) 98 })));
|
||||
assertEquals("Yw==", new String(new Base64().encode(new byte[] { (byte) 99 })));
|
||||
assertEquals("ZA==", new String(new Base64().encode(new byte[] { (byte) 100 })));
|
||||
assertEquals("ZQ==", new String(new Base64().encode(new byte[] { (byte) 101 })));
|
||||
assertEquals("Zg==", new String(new Base64().encode(new byte[] { (byte) 102 })));
|
||||
assertEquals("Zw==", new String(new Base64().encode(new byte[] { (byte) 103 })));
|
||||
assertEquals("aA==", new String(new Base64().encode(new byte[] { (byte) 104 })));
|
||||
|
||||
assertEquals("AA..", new String(new Base64(true).encode(new byte[] { (byte) 0 })));
|
||||
assertEquals("AQ..", new String(new Base64(true).encode(new byte[] { (byte) 1 })));
|
||||
assertEquals("Ag..", new String(new Base64(true).encode(new byte[] { (byte) 2 })));
|
||||
assertEquals("Aw..", new String(new Base64(true).encode(new byte[] { (byte) 3 })));
|
||||
assertEquals("BA..", new String(new Base64(true).encode(new byte[] { (byte) 4 })));
|
||||
assertEquals("BQ..", new String(new Base64(true).encode(new byte[] { (byte) 5 })));
|
||||
assertEquals("Bg..", new String(new Base64(true).encode(new byte[] { (byte) 6 })));
|
||||
assertEquals("Bw..", new String(new Base64(true).encode(new byte[] { (byte) 7 })));
|
||||
assertEquals("CA..", new String(new Base64(true).encode(new byte[] { (byte) 8 })));
|
||||
assertEquals("CQ..", new String(new Base64(true).encode(new byte[] { (byte) 9 })));
|
||||
assertEquals("Cg..", new String(new Base64(true).encode(new byte[] { (byte) 10 })));
|
||||
assertEquals("Cw..", new String(new Base64(true).encode(new byte[] { (byte) 11 })));
|
||||
assertEquals("DA..", new String(new Base64(true).encode(new byte[] { (byte) 12 })));
|
||||
assertEquals("DQ..", new String(new Base64(true).encode(new byte[] { (byte) 13 })));
|
||||
assertEquals("Dg..", new String(new Base64(true).encode(new byte[] { (byte) 14 })));
|
||||
assertEquals("Dw..", new String(new Base64(true).encode(new byte[] { (byte) 15 })));
|
||||
assertEquals("EA..", new String(new Base64(true).encode(new byte[] { (byte) 16 })));
|
||||
assertEquals("EQ..", new String(new Base64(true).encode(new byte[] { (byte) 17 })));
|
||||
assertEquals("Eg..", new String(new Base64(true).encode(new byte[] { (byte) 18 })));
|
||||
assertEquals("Ew..", new String(new Base64(true).encode(new byte[] { (byte) 19 })));
|
||||
assertEquals("FA..", new String(new Base64(true).encode(new byte[] { (byte) 20 })));
|
||||
assertEquals("FQ..", new String(new Base64(true).encode(new byte[] { (byte) 21 })));
|
||||
assertEquals("Fg..", new String(new Base64(true).encode(new byte[] { (byte) 22 })));
|
||||
assertEquals("Fw..", new String(new Base64(true).encode(new byte[] { (byte) 23 })));
|
||||
assertEquals("GA..", new String(new Base64(true).encode(new byte[] { (byte) 24 })));
|
||||
assertEquals("GQ..", new String(new Base64(true).encode(new byte[] { (byte) 25 })));
|
||||
assertEquals("Gg..", new String(new Base64(true).encode(new byte[] { (byte) 26 })));
|
||||
assertEquals("Gw..", new String(new Base64(true).encode(new byte[] { (byte) 27 })));
|
||||
assertEquals("HA..", new String(new Base64(true).encode(new byte[] { (byte) 28 })));
|
||||
assertEquals("HQ..", new String(new Base64(true).encode(new byte[] { (byte) 29 })));
|
||||
assertEquals("Hg..", new String(new Base64(true).encode(new byte[] { (byte) 30 })));
|
||||
assertEquals("Hw..", new String(new Base64(true).encode(new byte[] { (byte) 31 })));
|
||||
assertEquals("IA..", new String(new Base64(true).encode(new byte[] { (byte) 32 })));
|
||||
assertEquals("IQ..", new String(new Base64(true).encode(new byte[] { (byte) 33 })));
|
||||
assertEquals("Ig..", new String(new Base64(true).encode(new byte[] { (byte) 34 })));
|
||||
assertEquals("Iw..", new String(new Base64(true).encode(new byte[] { (byte) 35 })));
|
||||
assertEquals("JA..", new String(new Base64(true).encode(new byte[] { (byte) 36 })));
|
||||
assertEquals("JQ..", new String(new Base64(true).encode(new byte[] { (byte) 37 })));
|
||||
assertEquals("Jg..", new String(new Base64(true).encode(new byte[] { (byte) 38 })));
|
||||
assertEquals("Jw..", new String(new Base64(true).encode(new byte[] { (byte) 39 })));
|
||||
assertEquals("KA..", new String(new Base64(true).encode(new byte[] { (byte) 40 })));
|
||||
assertEquals("KQ..", new String(new Base64(true).encode(new byte[] { (byte) 41 })));
|
||||
assertEquals("Kg..", new String(new Base64(true).encode(new byte[] { (byte) 42 })));
|
||||
assertEquals("Kw..", new String(new Base64(true).encode(new byte[] { (byte) 43 })));
|
||||
assertEquals("LA..", new String(new Base64(true).encode(new byte[] { (byte) 44 })));
|
||||
assertEquals("LQ..", new String(new Base64(true).encode(new byte[] { (byte) 45 })));
|
||||
assertEquals("Lg..", new String(new Base64(true).encode(new byte[] { (byte) 46 })));
|
||||
assertEquals("Lw..", new String(new Base64(true).encode(new byte[] { (byte) 47 })));
|
||||
assertEquals("MA..", new String(new Base64(true).encode(new byte[] { (byte) 48 })));
|
||||
assertEquals("MQ..", new String(new Base64(true).encode(new byte[] { (byte) 49 })));
|
||||
assertEquals("Mg..", new String(new Base64(true).encode(new byte[] { (byte) 50 })));
|
||||
assertEquals("Mw..", new String(new Base64(true).encode(new byte[] { (byte) 51 })));
|
||||
assertEquals("NA..", new String(new Base64(true).encode(new byte[] { (byte) 52 })));
|
||||
assertEquals("NQ..", new String(new Base64(true).encode(new byte[] { (byte) 53 })));
|
||||
assertEquals("Ng..", new String(new Base64(true).encode(new byte[] { (byte) 54 })));
|
||||
assertEquals("Nw..", new String(new Base64(true).encode(new byte[] { (byte) 55 })));
|
||||
assertEquals("OA..", new String(new Base64(true).encode(new byte[] { (byte) 56 })));
|
||||
assertEquals("OQ..", new String(new Base64(true).encode(new byte[] { (byte) 57 })));
|
||||
assertEquals("Og..", new String(new Base64(true).encode(new byte[] { (byte) 58 })));
|
||||
assertEquals("Ow..", new String(new Base64(true).encode(new byte[] { (byte) 59 })));
|
||||
assertEquals("PA..", new String(new Base64(true).encode(new byte[] { (byte) 60 })));
|
||||
assertEquals("PQ..", new String(new Base64(true).encode(new byte[] { (byte) 61 })));
|
||||
assertEquals("Pg..", new String(new Base64(true).encode(new byte[] { (byte) 62 })));
|
||||
assertEquals("Pw..", new String(new Base64(true).encode(new byte[] { (byte) 63 })));
|
||||
assertEquals("QA..", new String(new Base64(true).encode(new byte[] { (byte) 64 })));
|
||||
assertEquals("QQ..", new String(new Base64(true).encode(new byte[] { (byte) 65 })));
|
||||
assertEquals("Qg..", new String(new Base64(true).encode(new byte[] { (byte) 66 })));
|
||||
assertEquals("Qw..", new String(new Base64(true).encode(new byte[] { (byte) 67 })));
|
||||
assertEquals("RA..", new String(new Base64(true).encode(new byte[] { (byte) 68 })));
|
||||
assertEquals("RQ..", new String(new Base64(true).encode(new byte[] { (byte) 69 })));
|
||||
assertEquals("Rg..", new String(new Base64(true).encode(new byte[] { (byte) 70 })));
|
||||
assertEquals("Rw..", new String(new Base64(true).encode(new byte[] { (byte) 71 })));
|
||||
assertEquals("SA..", new String(new Base64(true).encode(new byte[] { (byte) 72 })));
|
||||
assertEquals("SQ..", new String(new Base64(true).encode(new byte[] { (byte) 73 })));
|
||||
assertEquals("Sg..", new String(new Base64(true).encode(new byte[] { (byte) 74 })));
|
||||
assertEquals("Sw..", new String(new Base64(true).encode(new byte[] { (byte) 75 })));
|
||||
assertEquals("TA..", new String(new Base64(true).encode(new byte[] { (byte) 76 })));
|
||||
assertEquals("TQ..", new String(new Base64(true).encode(new byte[] { (byte) 77 })));
|
||||
assertEquals("Tg..", new String(new Base64(true).encode(new byte[] { (byte) 78 })));
|
||||
assertEquals("Tw..", new String(new Base64(true).encode(new byte[] { (byte) 79 })));
|
||||
assertEquals("UA..", new String(new Base64(true).encode(new byte[] { (byte) 80 })));
|
||||
assertEquals("UQ..", new String(new Base64(true).encode(new byte[] { (byte) 81 })));
|
||||
assertEquals("Ug..", new String(new Base64(true).encode(new byte[] { (byte) 82 })));
|
||||
assertEquals("Uw..", new String(new Base64(true).encode(new byte[] { (byte) 83 })));
|
||||
assertEquals("VA..", new String(new Base64(true).encode(new byte[] { (byte) 84 })));
|
||||
assertEquals("VQ..", new String(new Base64(true).encode(new byte[] { (byte) 85 })));
|
||||
assertEquals("Vg..", new String(new Base64(true).encode(new byte[] { (byte) 86 })));
|
||||
assertEquals("Vw..", new String(new Base64(true).encode(new byte[] { (byte) 87 })));
|
||||
assertEquals("WA..", new String(new Base64(true).encode(new byte[] { (byte) 88 })));
|
||||
assertEquals("WQ..", new String(new Base64(true).encode(new byte[] { (byte) 89 })));
|
||||
assertEquals("Wg..", new String(new Base64(true).encode(new byte[] { (byte) 90 })));
|
||||
assertEquals("Ww..", new String(new Base64(true).encode(new byte[] { (byte) 91 })));
|
||||
assertEquals("XA..", new String(new Base64(true).encode(new byte[] { (byte) 92 })));
|
||||
assertEquals("XQ..", new String(new Base64(true).encode(new byte[] { (byte) 93 })));
|
||||
assertEquals("Xg..", new String(new Base64(true).encode(new byte[] { (byte) 94 })));
|
||||
assertEquals("Xw..", new String(new Base64(true).encode(new byte[] { (byte) 95 })));
|
||||
assertEquals("YA..", new String(new Base64(true).encode(new byte[] { (byte) 96 })));
|
||||
assertEquals("YQ..", new String(new Base64(true).encode(new byte[] { (byte) 97 })));
|
||||
assertEquals("Yg..", new String(new Base64(true).encode(new byte[] { (byte) 98 })));
|
||||
assertEquals("Yw..", new String(new Base64(true).encode(new byte[] { (byte) 99 })));
|
||||
assertEquals("ZA..", new String(new Base64(true).encode(new byte[] { (byte) 100 })));
|
||||
assertEquals("ZQ..", new String(new Base64(true).encode(new byte[] { (byte) 101 })));
|
||||
assertEquals("Zg..", new String(new Base64(true).encode(new byte[] { (byte) 102 })));
|
||||
assertEquals("Zw..", new String(new Base64(true).encode(new byte[] { (byte) 103 })));
|
||||
assertEquals("aA..", new String(new Base64(true).encode(new byte[] { (byte) 104 })));
|
||||
}
|
||||
|
||||
public void testTriplets() {
|
||||
assertEquals("AAAA", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 0 })));
|
||||
assertEquals("AAAB", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 1 })));
|
||||
assertEquals("AAAC", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 2 })));
|
||||
assertEquals("AAAD", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 3 })));
|
||||
assertEquals("AAAE", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 4 })));
|
||||
assertEquals("AAAF", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 5 })));
|
||||
assertEquals("AAAG", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 6 })));
|
||||
assertEquals("AAAH", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 7 })));
|
||||
assertEquals("AAAI", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 8 })));
|
||||
assertEquals("AAAJ", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 9 })));
|
||||
assertEquals("AAAK", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 10 })));
|
||||
assertEquals("AAAL", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 11 })));
|
||||
assertEquals("AAAM", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 12 })));
|
||||
assertEquals("AAAN", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 13 })));
|
||||
assertEquals("AAAO", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 14 })));
|
||||
assertEquals("AAAP", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 15 })));
|
||||
assertEquals("AAAQ", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 16 })));
|
||||
assertEquals("AAAR", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 17 })));
|
||||
assertEquals("AAAS", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 18 })));
|
||||
assertEquals("AAAT", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 19 })));
|
||||
assertEquals("AAAU", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 20 })));
|
||||
assertEquals("AAAV", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 21 })));
|
||||
assertEquals("AAAW", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 22 })));
|
||||
assertEquals("AAAX", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 23 })));
|
||||
assertEquals("AAAY", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 24 })));
|
||||
assertEquals("AAAZ", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 25 })));
|
||||
assertEquals("AAAa", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 26 })));
|
||||
assertEquals("AAAb", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 27 })));
|
||||
assertEquals("AAAc", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 28 })));
|
||||
assertEquals("AAAd", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 29 })));
|
||||
assertEquals("AAAe", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 30 })));
|
||||
assertEquals("AAAf", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 31 })));
|
||||
assertEquals("AAAg", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 32 })));
|
||||
assertEquals("AAAh", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 33 })));
|
||||
assertEquals("AAAi", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 34 })));
|
||||
assertEquals("AAAj", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 35 })));
|
||||
assertEquals("AAAk", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 36 })));
|
||||
assertEquals("AAAl", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 37 })));
|
||||
assertEquals("AAAm", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 38 })));
|
||||
assertEquals("AAAn", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 39 })));
|
||||
assertEquals("AAAo", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 40 })));
|
||||
assertEquals("AAAp", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 41 })));
|
||||
assertEquals("AAAq", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 42 })));
|
||||
assertEquals("AAAr", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 43 })));
|
||||
assertEquals("AAAs", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 44 })));
|
||||
assertEquals("AAAt", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 45 })));
|
||||
assertEquals("AAAu", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 46 })));
|
||||
assertEquals("AAAv", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 47 })));
|
||||
assertEquals("AAAw", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 48 })));
|
||||
assertEquals("AAAx", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 49 })));
|
||||
assertEquals("AAAy", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 50 })));
|
||||
assertEquals("AAAz", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 51 })));
|
||||
assertEquals("AAA0", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 52 })));
|
||||
assertEquals("AAA1", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 53 })));
|
||||
assertEquals("AAA2", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 54 })));
|
||||
assertEquals("AAA3", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 55 })));
|
||||
assertEquals("AAA4", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 56 })));
|
||||
assertEquals("AAA5", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 57 })));
|
||||
assertEquals("AAA6", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 58 })));
|
||||
assertEquals("AAA7", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 59 })));
|
||||
assertEquals("AAA8", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 60 })));
|
||||
assertEquals("AAA9", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 61 })));
|
||||
assertEquals("AAA+", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 62 })));
|
||||
assertEquals("AAA/", new String(new Base64().encode(new byte[] { (byte) 0, (byte) 0, (byte) 63 })));
|
||||
|
||||
assertEquals("AAAA", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 0 })));
|
||||
assertEquals("AAAB", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 1 })));
|
||||
assertEquals("AAAC", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 2 })));
|
||||
assertEquals("AAAD", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 3 })));
|
||||
assertEquals("AAAE", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 4 })));
|
||||
assertEquals("AAAF", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 5 })));
|
||||
assertEquals("AAAG", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 6 })));
|
||||
assertEquals("AAAH", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 7 })));
|
||||
assertEquals("AAAI", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 8 })));
|
||||
assertEquals("AAAJ", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 9 })));
|
||||
assertEquals("AAAK", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 10 })));
|
||||
assertEquals("AAAL", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 11 })));
|
||||
assertEquals("AAAM", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 12 })));
|
||||
assertEquals("AAAN", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 13 })));
|
||||
assertEquals("AAAO", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 14 })));
|
||||
assertEquals("AAAP", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 15 })));
|
||||
assertEquals("AAAQ", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 16 })));
|
||||
assertEquals("AAAR", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 17 })));
|
||||
assertEquals("AAAS", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 18 })));
|
||||
assertEquals("AAAT", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 19 })));
|
||||
assertEquals("AAAU", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 20 })));
|
||||
assertEquals("AAAV", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 21 })));
|
||||
assertEquals("AAAW", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 22 })));
|
||||
assertEquals("AAAX", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 23 })));
|
||||
assertEquals("AAAY", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 24 })));
|
||||
assertEquals("AAAZ", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 25 })));
|
||||
assertEquals("AAAa", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 26 })));
|
||||
assertEquals("AAAb", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 27 })));
|
||||
assertEquals("AAAc", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 28 })));
|
||||
assertEquals("AAAd", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 29 })));
|
||||
assertEquals("AAAe", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 30 })));
|
||||
assertEquals("AAAf", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 31 })));
|
||||
assertEquals("AAAg", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 32 })));
|
||||
assertEquals("AAAh", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 33 })));
|
||||
assertEquals("AAAi", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 34 })));
|
||||
assertEquals("AAAj", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 35 })));
|
||||
assertEquals("AAAk", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 36 })));
|
||||
assertEquals("AAAl", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 37 })));
|
||||
assertEquals("AAAm", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 38 })));
|
||||
assertEquals("AAAn", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 39 })));
|
||||
assertEquals("AAAo", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 40 })));
|
||||
assertEquals("AAAp", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 41 })));
|
||||
assertEquals("AAAq", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 42 })));
|
||||
assertEquals("AAAr", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 43 })));
|
||||
assertEquals("AAAs", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 44 })));
|
||||
assertEquals("AAAt", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 45 })));
|
||||
assertEquals("AAAu", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 46 })));
|
||||
assertEquals("AAAv", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 47 })));
|
||||
assertEquals("AAAw", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 48 })));
|
||||
assertEquals("AAAx", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 49 })));
|
||||
assertEquals("AAAy", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 50 })));
|
||||
assertEquals("AAAz", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 51 })));
|
||||
assertEquals("AAA0", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 52 })));
|
||||
assertEquals("AAA1", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 53 })));
|
||||
assertEquals("AAA2", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 54 })));
|
||||
assertEquals("AAA3", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 55 })));
|
||||
assertEquals("AAA4", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 56 })));
|
||||
assertEquals("AAA5", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 57 })));
|
||||
assertEquals("AAA6", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 58 })));
|
||||
assertEquals("AAA7", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 59 })));
|
||||
assertEquals("AAA8", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 60 })));
|
||||
assertEquals("AAA9", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 61 })));
|
||||
assertEquals("AAA-", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 62 })));
|
||||
assertEquals("AAA_", new String(new Base64(true).encode(new byte[] { (byte) 0, (byte) 0, (byte) 63 })));
|
||||
}
|
||||
|
||||
public void testKnownEncodings() {
|
||||
assertEquals("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg==", new Base64()
|
||||
.encodeToString("The quick brown fox jumped over the lazy dogs.".getBytes()));
|
||||
assertEquals("SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg==", new Base64()
|
||||
.encodeToString("It was the best of times, it was the worst of times.".getBytes()));
|
||||
assertEquals("aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw==", new Base64()
|
||||
.encodeToString("http://jakarta.apache.org/commmons".getBytes()));
|
||||
assertEquals("QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1h4WXlaeg==", new Base64()
|
||||
.encodeToString("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".getBytes()));
|
||||
assertEquals("eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0=", new Base64()
|
||||
.encodeToString("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }".getBytes()));
|
||||
assertEquals("eHl6enkh", new String(new Base64().encode("xyzzy!".getBytes())));
|
||||
|
||||
assertEquals("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg..", new Base64(true)
|
||||
.encodeToString("The quick brown fox jumped over the lazy dogs.".getBytes()));
|
||||
assertEquals("SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg..", new Base64(true)
|
||||
.encodeToString("It was the best of times, it was the worst of times.".getBytes()));
|
||||
assertEquals("aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw..", new Base64(true)
|
||||
.encodeToString("http://jakarta.apache.org/commmons".getBytes()));
|
||||
assertEquals("QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1h4WXlaeg..", new Base64(true)
|
||||
.encodeToString("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".getBytes()));
|
||||
assertEquals("eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0.", new Base64(true)
|
||||
.encodeToString("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }".getBytes()));
|
||||
assertEquals("eHl6enkh", new String(new Base64(true).encode("xyzzy!".getBytes())));
|
||||
}
|
||||
|
||||
public void testKnownDecodings() {
|
||||
assertEquals("The quick brown fox jumped over the lazy dogs.", new String(new Base64()
|
||||
.decodeFromString("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg==")));
|
||||
assertEquals("It was the best of times, it was the worst of times.", new String(new Base64()
|
||||
.decodeFromString("SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg==")));
|
||||
assertEquals("http://jakarta.apache.org/commmons", new String(new Base64()
|
||||
.decodeFromString("aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw==")));
|
||||
assertEquals("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", new String(new Base64()
|
||||
.decodeFromString("QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1h4WXlaeg==")));
|
||||
assertEquals("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }", new String(new Base64()
|
||||
.decodeFromString("eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0=")));
|
||||
assertEquals("xyzzy!", new String(new Base64().decodeFromString("eHl6enkh")));
|
||||
|
||||
assertEquals("The quick brown fox jumped over the lazy dogs.", new String(new Base64(true)
|
||||
.decodeFromString("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg..")));
|
||||
assertEquals("It was the best of times, it was the worst of times.", new String(new Base64(true)
|
||||
.decodeFromString("SXQgd2FzIHRoZSBiZXN0IG9mIHRpbWVzLCBpdCB3YXMgdGhlIHdvcnN0IG9mIHRpbWVzLg..")));
|
||||
assertEquals("http://jakarta.apache.org/commmons", new String(new Base64(true)
|
||||
.decodeFromString("aHR0cDovL2pha2FydGEuYXBhY2hlLm9yZy9jb21tbW9ucw..")));
|
||||
assertEquals("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", new String(new Base64(true)
|
||||
.decodeFromString("QWFCYkNjRGRFZUZmR2dIaElpSmpLa0xsTW1Obk9vUHBRcVJyU3NUdFV1VnZXd1h4WXlaeg..")));
|
||||
assertEquals("{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }", new String(new Base64(true)
|
||||
.decodeFromString("eyAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5IH0.")));
|
||||
assertEquals("xyzzy!", new String(new Base64(true).decodeFromString("eHl6enkh")));
|
||||
}
|
||||
|
||||
public void testNonBase64Test() throws Exception {
|
||||
byte[] bArray = { '%' };
|
||||
|
||||
try {
|
||||
byte[] result = new Base64().decode(bArray);
|
||||
assertTrue("The result should be empty as the test encoded content did "
|
||||
+ "not contain any valid base 64 characters", result.length == 0);
|
||||
} catch (Exception e) {
|
||||
fail("Exception was thrown when trying to decode "
|
||||
+ "invalid base64 encoded data - RFC 2045 requires that all "
|
||||
+ "non base64 character be discarded, an exception should not" + " have been thrown");
|
||||
}
|
||||
}
|
||||
|
||||
public void testIgnoringNonBase64InDecode() throws Exception {
|
||||
assertEquals(
|
||||
"The quick brown fox jumped over the lazy dogs.",
|
||||
new String(
|
||||
new Base64()
|
||||
.decodeFromString("VGhlIH@$#$@%F1aWN@#@#@@rIGJyb3duIGZve\n\r\t%#%#%#%CBqd##$#$W1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg==")));
|
||||
|
||||
assertEquals(
|
||||
"The quick brown fox jumped over the lazy dogs.",
|
||||
new String(
|
||||
new Base64(true)
|
||||
.decodeFromString("VGhlIH@$#$@%F1aWN@#@#@@rIGJyb3duIGZve\n\r\t%#%#%#%CBqd##$#$W1wZWQgb3ZlciB0aGUgbGF6eSBkb2dzLg..")));
|
||||
}
|
||||
|
||||
public void testDecodeWithWhitespace() throws Exception {
|
||||
String orig = "I am a late night coder.";
|
||||
|
||||
byte[] encodedArray = new Base64().encode(orig.getBytes());
|
||||
|
||||
StringBuffer intermediate = new StringBuffer(new String(encodedArray));
|
||||
intermediate.insert(2, ' ');
|
||||
intermediate.insert(5, '\t');
|
||||
intermediate.insert(10, '\r');
|
||||
intermediate.insert(15, '\n');
|
||||
|
||||
byte[] encodedWithWhitespace = intermediate.toString().getBytes();
|
||||
byte[] decodedWithWhitespace = new Base64().decode(encodedWithWhitespace);
|
||||
|
||||
String dest = new String(decodedWithWhitespace);
|
||||
|
||||
assertEquals(orig, dest);
|
||||
}
|
||||
|
||||
public void testEncodePaddingChar() {
|
||||
assertEquals("=", new String(new Base64().decode(new Base64().encode("=".getBytes()))));
|
||||
assertEquals(".", new String(new Base64().decode(new Base64().encode(".".getBytes()))));
|
||||
assertEquals("=", new String(new Base64(true).decode(new Base64(true).encode("=".getBytes()))));
|
||||
assertEquals(".", new String(new Base64(true).decode(new Base64(true).encode(".".getBytes()))));
|
||||
}
|
||||
|
||||
public void testUrlSafety() throws Exception {
|
||||
byte[] bytes = new byte[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
bytes[i] = (byte) i;
|
||||
}
|
||||
byte[] encoded = new Base64(true).encode(bytes);
|
||||
String encodedString = new String(encoded, "UTF-8");
|
||||
String urlEncoded = URLEncoder.encode(encodedString, "UTF-8");
|
||||
assertEquals(encodedString, urlEncoded);
|
||||
String urlDecoded = URLDecoder.decode(urlEncoded, "UTF-8");
|
||||
assertEquals(encodedString, urlDecoded);
|
||||
byte[] decoded = new Base64(true).decode(urlDecoded.getBytes("UTF-8"));
|
||||
assertEquals(bytes.length, decoded.length);
|
||||
for (int i = 0; i < 256; i++) {
|
||||
assertEquals(bytes[i], decoded[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user