/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.core.designer.id;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.teiid.core.designer.CoreModelerPlugin;
/**
* IDGenerator
* @since 8.0
*/
public class IDGenerator {
private static final IDGenerator INSTANCE = new IDGenerator();
/**
* Obtain the shared instance of this class.
* @return the statically shared instance of this class.
*/
public static IDGenerator getInstance() {
return INSTANCE;
}
/** ObjectIDFactory instances keyed by protocol */
private final Map factories;
private final Set protocols;
private ObjectIDFactory defaultFactory;
public IDGenerator() {
this.factories = new HashMap();
this.protocols = new HashSet();
// Initialize default factory ...
final ObjectIDFactory newDefaultFactory = new UUIDFactory();
addFactory( newDefaultFactory );
if ( !this.hasDefaultFactory() ) {
this.setDefaultFactory(newDefaultFactory);
}
}
/**
* Method that creates and adds to this generator all the built-in factories, and if there is no default
* factory, set the default factory to the {@link UUIDFactory}.
* This method may be called multiple times without side effect.
*/
public void addBuiltInFactories() {
// Add the UUID factory as the default ...
final ObjectIDFactory newDefaultFactory = new UUIDFactory();
addFactory( newDefaultFactory );
if ( !this.hasDefaultFactory() ) {
this.setDefaultFactory(newDefaultFactory);
}
addFactory( new IntegerIDFactory() );
addFactory( new LongIDFactory() );
addFactory( new StringIDFactory() );
}
/**
* Supply to this generator a new factory for a type of {@link ObjectID}.
* This method has no effect if the factory is null, or if this generator already knows
* about the factory.
* @param factory the new factory
*/
public void addFactory( final ObjectIDFactory factory ) {
if ( factory == null ) {
return;
}
final String protocol = factory.getProtocol();
// See if the factory is already known ...
if ( !this.factories.containsKey(protocol) ) {
this.factories.put(protocol,factory);
}
this.protocols.add(protocol);
}
/**
* Remove a factory from this generator.
* This method has no effect if the supplied protocol doesn't match the protocol of any descriptor
* known to this generator.
* @param protocol the protocol for which the factory is to be removed
* @return whether a factory was found and removed for the supplied protocol
*/
public boolean removeFactory(String protocol) {
if ( protocol == null ) {
return false;
}
final Object previous = this.factories.remove(protocol);
if ( previous != null ) {
this.protocols.remove(protocol);
return true;
}
return false;
}
/**
* Method to obtain the collection of {@link ObjectIDFactory} instances that each describe
* one of the types of {@link ObjectID}s that are available to this generator.
* @return the collection of {@link ObjectIDFactory} instances.
*/
public Collection getFactories() {
// Currently, we get the collection of values from the 'factories' map. This is okay,
// because although not terribly efficient, this method is not intended to be called very
// frequently
return factories.values();
}
/**
* Method to obtain the collection of {@link ObjectIDFactory} instances that each describe
* one of the types of {@link ObjectID}s that are available to this generator.
* @return the collection of {@link ObjectIDFactory} instances.
*/
public ObjectIDFactory getFactory( final String protocol ) {
return (ObjectIDFactory) this.factories.get(protocol);
}
/**
* Method to obtain the set of {@link java.lang.String String} protocols. This is a utility that merely obtains the
* protocols from the factories.
* @return the Set of String protocols; never null
*/
public Set getProtocols() {
return factories.keySet();
}
/**
* Return whether there is a factory that is used by default for the {@link #create()} method is invoked.
* @return true if there is a default factory, or false otherwise
*/
public boolean hasDefaultFactory() {
return defaultFactory != null;
}
/**
* Get the factory that is used by default for the {@link #create()} method is invoked.
* @return the default factory, or null if there is no default factory
*/
public ObjectIDFactory getDefaultFactory() {
return defaultFactory;
}
/**
* Set the factory that should be used by default for the {@link #create()} method is invoked.
* @param factory the factory that should be used by default; may be null if no default is to be allowed.
*/
public void setDefaultFactory(final ObjectIDFactory factory) {
defaultFactory = factory;
}
/**
* Set the factory that should be used by default for the {@link #create()} method is invoked.
* @param protocol the protocol for factory that should be used by default; may be null if no default
* is to be allowed.
*/
public void setDefaultFactory(final String protocol) {
final ObjectIDFactory factory = getFactory(protocol); // null if protocol doesn't match
defaultFactory = factory;
}
/**
* Create a new {@link ObjectID} using the default factory
* @return the new ObjectID
*/
public ObjectID create() {
if ( this.defaultFactory != null ) {
return this.defaultFactory.create();
}
// Invalid protocol
throw new IllegalArgumentException(CoreModelerPlugin.Util.getString("IDGenerator.No_default_id_factory_has_been_defined")); //$NON-NLS-1$
}
/**
* Create a new {@link ObjectID} for the type specified by the protocol
* @param protocol the protocol of the type of {@link ObjectID} to be created; may not be null
* @return the new ObjectID
*/
public ObjectID create( final String protocol ) {
if (protocol == null) {
final String msg = CoreModelerPlugin.Util.getString("IDGenerator.The_protocol_may_not_be_null"); //$NON-NLS-1$
throw new IllegalArgumentException(msg);
}
// Get the factory ...
final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(protocol);
if ( factory != null ) {
// Create the new ObjectID ...
return factory.create();
}
// Invalid protocol
throw new IllegalArgumentException(CoreModelerPlugin.Util.getString("IDGenerator.The_specified_ObjectID_protocol___8",protocol)); //$NON-NLS-1$
}
/**
* Convenience method for obtaining the stringified form of an ObjectID.
* @param id
* @return
*/
public String toString( final ObjectID id ) {
return id.toString();
}
/**
* Convenience method for obtaining the stringified form of an ObjectID.
* @param id
* @return
*/
public String toString( final ObjectID id, final char delim ) {
return id.toString(delim);
}
/**
* Attempt to convert the specified string to the appropriate ObjectID instance.
* @param id the stringified id of the form <code>protocol:value</code>, where
* <code>protocol</code> defines the protocol of the ID, and <code>value</code
* contains the global identifier value; may never be null
* @return the ObjectID instance for the stringified ID
* @throws InvalidIDException if the specified string does not contain a valid ObjectID
* or if the protocol is unknown
*/
public ObjectID stringToObject(String id) throws InvalidIDException {
if (id == null) {
final String msg = CoreModelerPlugin.Util.getString("IDGenerator.The_stringified_ID_may_not_be_null"); //$NON-NLS-1$
throw new IllegalArgumentException(msg);
}
// Parse the string
final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(id,this.protocols);
// Find the appropriate factory and parse the id ...
final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(parsedID.getProtocol());
ObjectID result = null;
if ( factory != null ) {
result = factory.stringWithoutProtocolToObject(parsedID.getRemainder());
}
if ( result == null ) {
throw new InvalidIDException(CoreModelerPlugin.Util.getString("IDGenerator.The_stringified_ObjectID_has_an_unknown_protocol___16") + parsedID.getProtocol()); //$NON-NLS-1$
}
return result;
}
/**
* Attempt to convert the specified string to the appropriate ObjectID instance.
* @param id the stringified id of the form <code>protocol:value</code>, where
* <code>protocol</code> defines the protocol of the ID, and <code>value</code
* contains the global identifier value; may never be null
* @return the ObjectID instance for the stringified ID
* @throws InvalidIDException if the specified string does not contain a valid ObjectID
* or if the protocol is unknown
*/
public ObjectID stringToObject(String id, String protocol) throws InvalidIDException {
if (id == null) {
final String msg = CoreModelerPlugin.Util.getString("IDGenerator.The_stringified_ID_may_not_be_null"); //$NON-NLS-1$
throw new IllegalArgumentException(msg);
}
// Parse the string
final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(id,protocol);
// Find the appropriate factory and parse the id ...
final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(parsedID.getProtocol());
ObjectID result = null;
if ( factory != null ) {
result = factory.stringWithoutProtocolToObject(parsedID.getRemainder());
}
if ( result == null ) {
throw new InvalidIDException(CoreModelerPlugin.Util.getString("IDGenerator.The_stringified_ObjectID_has_an_unknown_protocol___16") + parsedID.getProtocol()); //$NON-NLS-1$
}
return result;
}
/**
* Attempt to convert the specified string to the appropriate ObjectID instance.
* @param id the stringified id of the form <code>protocol:value</code>, where
* <code>protocol</code> defines the protocol of the ID, and <code>value</code
* contains the global identifier value; may never be null
* @return the ObjectID instance for the stringified ID
* @throws InvalidIDException if the specified string does not contain a valid ObjectID
* or if the protocol is unknown
*/
public ObjectID stringToObject(String id, char delim) throws InvalidIDException {
if (id == null) {
final String msg = CoreModelerPlugin.Util.getString("IDGenerator.The_stringified_ID_may_not_be_null"); //$NON-NLS-1$
throw new IllegalArgumentException(msg);
}
// Parse the string
final ParsedObjectID parsedID = ParsedObjectID.parsedStringifiedObjectID(id,delim);
// Find the appropriate factory and parse the id ...
final ObjectIDFactory factory = (ObjectIDFactory) this.factories.get(parsedID.getProtocol());
ObjectID result = null;
if ( factory != null ) {
result = factory.stringWithoutProtocolToObject(parsedID.getRemainder());
}
if ( result == null ) {
throw new InvalidIDException(CoreModelerPlugin.Util.getString("IDGenerator.The_stringified_ObjectID_has_an_unknown_protocol___16") + parsedID.getProtocol()); //$NON-NLS-1$
}
return result;
}
}