06-20-2007 11:19 AM
12-07-2007 09:11 AM
12-07-2007 09:55 AM
12-10-2007 01:01 PM
03-27-2008 09:45 AM
04-02-2008 04:06 AM
04-02-2008 11:49 AM
04-03-2008 03:00 AM
Step 4: Ensure you have a clean repository (example: clean oracle schema).
04-22-2008 07:33 PM
package com.nkics.alfrescox.tool;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.rmi.RemoteException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import org.alfresco.webservice.authentication.AuthenticationFault;
import org.alfresco.webservice.repository.QueryResult;
import org.alfresco.webservice.repository.RepositoryFault;
import org.alfresco.webservice.types.CML;
import org.alfresco.webservice.types.CMLCreate;
import org.alfresco.webservice.types.NamedValue;
import org.alfresco.webservice.types.ParentReference;
import org.alfresco.webservice.types.Query;
import org.alfresco.webservice.types.Reference;
import org.alfresco.webservice.types.ResultSet;
import org.alfresco.webservice.types.ResultSetRow;
import org.alfresco.webservice.types.Store;
import org.alfresco.webservice.util.AuthenticationUtils;
import org.alfresco.webservice.util.Constants;
import org.alfresco.webservice.util.ISO9075;
import org.alfresco.webservice.util.Utils;
import org.alfresco.webservice.util.WebServiceFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <pre>
* Create a Category hierarchy in Alfresco from a plain text file.
*
* This Class uses the Alfresco Web Services Client to connect to an Alfresco CMS.
*
* <b>Usage:</b> java com.nkics.alfrescox.tool.CategoryImportTool <filename>
* <ul>filename - the text file containing the categories to be created.</ul>
*
* The text file should contain one category path (hierarchy) per line.
* Each category path is formatted like this: /cm:Parent/cm:SubCategory/cm:SubSubCategory
* Parent categories that do not exist will be created automatically.
*
* This class logs messages using the Common Logging package.
*
* Many of the methods in this class were defined in a reusable manner. In other words, You don't have to execute this class
* from the command line. Any of the public methods can be used to leverage all or part of the functionality provided by this tool.
*
* For example
* <ul>
* <li>To Create a Category: Simply create an instance of CategoryImportTool, and call createCategory(String path).
* <li>To Create multiple Categories from any source: Simply create an instance of CategoryImportTool, and call createCategories(Collection categories).
* </pre>
* @author swick April 22, 2009
*/
public class CategoryImportTool
{
public static final String ALFRESCO_USERNAME_PROPERTY = "repository.username";
public static final String ALFRESCO_PASSWORD_PROPERTY = "repository.password";
public static final String ALFRESCO_WEBSERVICECLIENT_PROPERTIES = "/alfresco/webserviceclient.properties";
private static final String ROOT_CATEGORY = "/cm:generalclassifiable";
private final String SUBCATEGORIES = "subcategories"; // the propertyname of subcategories
private final String SUBCATEGORIES_Q = Constants.createQNameString(Constants.NAMESPACE_CONTENT_MODEL, SUBCATEGORIES);
private final String CATEGORY = "category"; // the propertyname of subcategories
private final String CATEGORY_Q = Constants.createQNameString(Constants.NAMESPACE_CONTENT_MODEL, CATEGORY);
private final Store STORE = new Store(Constants.WORKSPACE_STORE, "SpacesStore");
/** Maps Parent Category Paths to Reference objects. Caches Parent Category lookups. **/
private Map<String,Reference> ROOT_REFERENCE_CACHE = new HashMap<String,Reference>();
private final Log logger = LogFactory.getLog(getClass());
/**
* Invoke the CategoryImportTool from the command line.
*
* @param args Command line arguments. arg[0] should be the filename containing the categories to import.
*/
public static void main(String[] args) throws Exception
{
if (args.length == 0)
printUsage();
CategoryImportTool migration = new CategoryImportTool();
migration.runApp(args[0]);
}
/**
* This method creates an Alfresco Web Service session {@link #setUp()}, reads the categories to
* import from the filename provided {@link #readCategoriesFromFile(String)}, creates each category,
* and ends the Alfresco web service session.
* @param filename is the name of a file on the local filesystem to import.
* @throws AuthenticationFault if there is a problem creating the Alfresco web service session. (username/password is invalid, or alfresco/webserviceclient.properties cannot be found or cannot connect to the URL specified)
* @throws RemoteException - There was a problem querying for or creating a category.
* @throws IOException - There was a problem reading the import file, the file doesn't exist, or you don't have permission to read the file.
*/
public void runApp(String filename) throws IOException
{
logger.info("Importing categories from "+filename);
setUp();
Collection<String> categories = readCategoriesFromFile(filename);
createCategories(categories);
tearDown();
logger.info("Category import completed.");
}
/**
* Read categories from a file into a Collection.
* This method simply adds each line from the file into the Collection.
* Blank lines and comments (lines starting with a # character) are ignored (they are not included in the Collection.
* @param fileName is the full path to a file to open for reading.
* @return a new Collection of Strings, one per line in the file.
* @throws IOException if there is a problem reading the filename specified.
*/
public Collection<String> readCategoriesFromFile(String fileName) throws IOException
{
BufferedReader in = new BufferedReader(new FileReader(fileName));
Vector<String> categories = new Vector<String>();
String str = null;
while ((str = in.readLine()) != null)
{
if(str.trim().length()==0)
continue; // skip blank lines
if(str.trim().startsWith("#"))
continue; // skip comments starting with the # character
categories.add(str);
}
in.close();
return categories;
}
/**
* This method loops over the Collection provided and invokes {@link #createCategory(String)}
* @param categories is a Collection of Strings, where each String is a category path to be created. example: "/cm:CatA/cm:Cat1/cm:CatI"
* @throws RemoteException is thrown from {@link #createCategory(String)} if there is a problem creating a category in Alfresco.
*/
public void createCategories(Collection<String> categories) throws RemoteException
{
for (String category : categories)
createCategory(category);
}
/**
* <pre>
* Create a Category in Alfresco. This method will automatically create any parent categories if they do not exist.
* If the Category already exist, it will be skipped without throwing an exception.
*
* The following messages are written using the Common Logging package
* </pre>
* <ul>
* <li><em>category already exists: {path}</em> # Logged at the INFO level if the category already exists.
* <li><em>creating category: {path}</em> # Logged at the INFO level if the category is being created (it does not exist).
* </ul>
* @param path is a Category Path (hierarchy) like "/cm:CatA/cm:Cat1/cm:CatI"
* @throws RemoteException from {@link #createCategory(String, ParentReference)} if Alfresco reports a problem creating the category.
*/
public void createCategory(String path) throws RemoteException
{
// Recursively create parent categories, if necessary.
Reference rootRef = null;
String parentCategoryPath = getParentCategoryPath(path);
while((rootRef=getRootReference(parentCategoryPath))==null)
{
createCategory(parentCategoryPath);
}
// Make sure the category doesn't already exist in Alfresco.
if(getCategory(path)!=null)
{
logger.info("category already exists: "+path);
return;
}
// Create the category.
logger.info("creating category:" + path);
String childCategoryName = getChildCategoryName(path);
ParentReference parentRef = new ParentReference(STORE, rootRef.getUuid(), null, SUBCATEGORIES_Q, Constants.createQNameString(Constants.NAMESPACE_CONTENT_MODEL, childCategoryName));
createCategory(childCategoryName, parentRef);
}
/**
* Get the Parent categories from the category path provided.
*
* @param path a Category path like "/cm:CatA/cm:Cat1/cm:CatI"
* @return all text up to the last / character, or null if there is no / character in the path provided. ie: "/cm:CatA/cm:Cat1"
*/
protected String getParentCategoryPath(String path)
{
if(path.lastIndexOf("/")<=0)
return null;
return path.substring(0, path.lastIndexOf("/"));
}
/**
* Get the child category name from the category path provided.
*
* @param path a Category path like "/cm:CatA/cm:Cat1/cm:CatI"
* @return all text from the last "/cm:" character sequence to the end of the path. ie: "CatI"
*/
protected String getChildCategoryName(String path)
{
return path.substring(path.lastIndexOf("/cm:")+4); // get the last category and strip off the "/cm:".
}
/**
* Actually create the Category described by the parentRef and categoryName provided
* @param categoryName is just the Name of the category to be created, without a namespace. ie: "CatI"
* @param parentRef is a reference to the parent category. ie: "/cm:CatA/cm:Cat1"
* @throws RemoteException
*/
protected void createCategory(String categoryName, ParentReference parentRef) throws RemoteException
{
NamedValue[] properties = new NamedValue[] { Utils.createNamedValue(Constants.PROP_NAME, categoryName) };
CMLCreate create = new CMLCreate("1", parentRef, null, null, null, CATEGORY_Q, properties);
CML cml = new CML();
cml.setCreate(new CMLCreate[] { create });
WebServiceFactory.getRepositoryService().update(cml);
}
/**
* Get the Parent Category specified. Root Categories are cached to improve performance and reduce load on the Alfresco server.
* @param parentCategoryPath is a path relative to /cm:generalclassifiable (ROOT_CATEGORY). Can be null, in which case ROOT_CATEGORY is returned.
* @return a Reference to the Root Category
* @throws RemoteException if {@link #getCategory(String)} throws this exception.
* @throws RepositoryFault if {@link #getCategory(String)} throws this exception.
* @see getCategory(String)
*/
private Reference getRootReference(String parentCategoryPath) throws RepositoryFault, RemoteException
{
// Return Cached Reference, if available.
if(ROOT_REFERENCE_CACHE.containsKey(parentCategoryPath))
return ROOT_REFERENCE_CACHE.get(parentCategoryPath);
// Get the Category from Alfresco, cache it, and return it.
Reference r = getCategory(parentCategoryPath);
if(r!=null)
ROOT_REFERENCE_CACHE.put(parentCategoryPath, r); // Add Reference to cache.
return r;
}
/**
* Get a Category from Alfresco.
* @param categoryPath is a path relative to /cm:generalclassifiable (ROOT_CATEGORY). Can be null, in which case /cm:generalclassifiable is returned.
* @return a Reference to the Category requested, or null if the category doesn't exist.
* @throws RemoteException
* @throws RepositoryFault
*/
public Reference getCategory(String categoryPath) throws RepositoryFault, RemoteException
{
String luceneQueryString = "PATH:\""+ROOT_CATEGORY+(categoryPath==null?"":encodeCategoryPath(categoryPath))+"\"";
Query query = new Query(Constants.QUERY_LANG_LUCENE, luceneQueryString);
QueryResult result = WebServiceFactory.getRepositoryService().query(STORE, query, true);
ResultSet rs = result.getResultSet();
if(rs.getTotalRowCount()==0)
return null;
ResultSetRow[] rows = rs.getRows();
String uuid = rows[0].getNode().getId();
return new Reference(STORE, uuid, null);
}
/**
* Apply ISO9075 encoding to the Category Path provided.
*
* @param categoryPath is a String like "/cm:Sports/cm:Water Polo"
* @return the categoryPath provided with ISO9075 encoding applied to each category in the path, like "/cm:Sports/cm:Water_x0020_Polo".
*/
public static final String encodeCategoryPath(String categoryPath)
{
categoryPath = categoryPath.substring(4); // Strip off the leading '/cm:'
String[] categories = categoryPath.split("/cm:"); // Split the category path by the remaining '/cm:' strings.
StringBuffer encodedCategoryPath = new StringBuffer();
for(String category : categories)
{
encodedCategoryPath.append("/cm:");
encodedCategoryPath.append(ISO9075.encode(category));
}
return encodedCategoryPath.toString();
}
/**
* Creates an Alfresco web service session. Called by {@link #runApp(String)}.
* <p>
* By default the username and password are "admin". The default values can be overridden by adding the {@link #ALFRESCO_USERNAME_PROPERTY}
* and {@link #ALFRESCO_PASSWORD_PROPERTY} to the {@link #ALFRESCO_WEBSERVICECLIENT_PROPERTIES} file, or by
* specifying these properties on the Java command line with the "-D" command line argument. System properties will take precedence
* over {@link #ALFRESCO_WEBSERVICECLIENT_PROPERTIES}.
* @see #ALFRESCO_USERNAME_PROPERTY
* @see #ALFRESCO_PASSWORD_PROPERTY
* @see #ALFRESCO_WEBSERVICECLIENT_PROPERTIES
* @throws AuthenticationFault if there is a problem logging into the Alfresco web service with the username and password provided.
* @throws IOException if there is a problem reading ALFRESCO_WEBSERVICECLIENT_PROPERTIES from the classloader.
*/
public void setUp() throws AuthenticationFault, IOException
{
// Set the Default values.
String username = "admin";
String password = "admin";
// Attempt to read the username and password from the Alfresco web service client properties file.
InputStream is = getClass().getResourceAsStream(ALFRESCO_WEBSERVICECLIENT_PROPERTIES);
if(is!=null)
{
Properties properties = new Properties();
properties.load(is);
username = getUsername(properties, username);
password = getPassword(properties, password);
}
// Attempt to read the username and password from the System properties.
username = getUsername(System.getProperties(), username);
password = getPassword(System.getProperties(), password);
logger.info("creating Alfresco web service client session with username '"+username+"' and password '"+password+"'.");
AuthenticationUtils.startSession(username, password);
}
protected String getUsername(Properties p, String originalValue)
{
if(p.containsKey(ALFRESCO_USERNAME_PROPERTY))
return p.getProperty(ALFRESCO_USERNAME_PROPERTY);
return originalValue;
}
protected String getPassword(Properties p, String originalValue)
{
if(p.containsKey(ALFRESCO_PASSWORD_PROPERTY))
return p.getProperty(ALFRESCO_PASSWORD_PROPERTY);
return originalValue;
}
/**
* Ends the Alfresco web service session. Called by {@link #runApp(String)}.
*/
public void tearDown()
{
AuthenticationUtils.endSession();
}
protected static void printUsage()
{
System.out.println("java "+CategoryImportTool.class.getName()+" <filename>");
}
}
# Consultant Categories
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:AL
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:AK
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:AS
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:AZ
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:AR
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:CA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:CO
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:CT
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:DE
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:DC
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:FM
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:FL
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:GA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:GU
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:HI
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:ID
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:IL
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:IN
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:IA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:KS
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:KY
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:LA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:ME
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MH
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MD
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MI
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MN
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MS
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MO
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MT
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NE
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NV
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NH
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NJ
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NM
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NY
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:NC
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:ND
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:MP
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:OH
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:OK
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:OR
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:PW
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:PA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:PR
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:RI
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:SC
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:SD
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:TN
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:TX
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:UT
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:VT
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:VI
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:VA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:WA
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:WV
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:WI
/cm:Audience/cm:Consultants/cm:Regions/cm:USA/cm:WY
# Distributor Categories
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:AL
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:AK
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:AS
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:AZ
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:AR
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:CA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:CO
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:CT
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:DE
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:DC
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:FM
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:FL
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:GA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:GU
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:HI
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:ID
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:IL
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:IN
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:IA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:KS
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:KY
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:LA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:ME
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MH
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MD
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MI
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MN
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MS
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MO
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MT
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NE
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NV
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NH
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NJ
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NM
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NY
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:NC
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:ND
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:MP
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:OH
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:OK
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:OR
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:PW
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:PA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:PR
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:RI
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:SC
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:SD
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:TN
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:TX
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:UT
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:VT
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:VI
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:VA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:WA
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:WV
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:WI
/cm:Audience/cm:Distributors/cm:Regions/cm:USA/cm:WY
# Star Retailer Categories
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:AL
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:AK
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:AS
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:AZ
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:AR
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:CA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:CO
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:CT
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:DE
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:DC
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:FM
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:FL
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:GA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:GU
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:HI
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:ID
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:IL
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:IN
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:IA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:KS
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:KY
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:LA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:ME
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MH
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MD
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MI
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MN
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MS
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MO
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MT
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NE
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NV
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NH
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NJ
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NM
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NY
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:NC
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:ND
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:MP
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:OH
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:OK
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:OR
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:PW
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:PA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:PR
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:RI
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:SC
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:SD
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:TN
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:TX
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:UT
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:VT
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:VI
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:VA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:WA
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:WV
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:WI
/cm:Audience/cm:Retailers/cm:Regions/cm:USA/cm:WY
04-25-2008 11:00 AM
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.