Add d:period data type (MOB-750)

- persistence, type conversion, and tests
- test model and index
- default set of implementations and tests

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14504 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind
2009-06-02 14:45:07 +00:00
parent abeb02268a
commit a8ac68a6e6
31 changed files with 2218 additions and 2 deletions

View File

@@ -58,6 +58,7 @@ public interface DataTypeDefinition
public QName ASSOC_REF = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "assocref");
public QName PATH = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "path");
public QName LOCALE = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "locale");
public QName PERIOD = QName.createQName(NamespaceService.DICTIONARY_MODEL_1_0_URI, "period");
/**

View File

@@ -0,0 +1,167 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.repository;
import java.io.Serializable;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Implementation for the period data type "d:period" A period is specified by the period type and an optional
* expression. The string value is periodType|expression Examples are: none day - one day day|3 - 3 days week - one week
* week|1 - one week week|2 - two weeks month year monthend quarterend The period type specifies a period
* implementation. This is registered with this class and is used to when adding the period to a date, handles any
* processing of the expression, reports if the expression is not required, optional or mandatory.
*
* @author andyh
*/
@SuppressWarnings("unchecked")
public class Period implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -7978001474638355909L;
// Providers do not serialize
transient private static ConcurrentHashMap<String, PeriodProvider> providers = new ConcurrentHashMap<String, PeriodProvider>();
/**
* Register a provider
* @param periodProvider
*/
public static void registerProvider(PeriodProvider periodProvider)
{
providers.put(periodProvider.getPeriodType(), periodProvider);
}
/**
* Find a provider
* @param periodType
* @return the provider
* @throws IllegalStateException of there is no implementation
*/
public static PeriodProvider getProvider(String periodType)
{
PeriodProvider provider = providers.get(periodType);
if (provider == null)
{
throw new IllegalStateException("No period provider for period type " + periodType);
}
return provider;
}
/**
* Get the set of registered providers
* @return - the set of registered providers
*/
public static Set<String> getProviderNames()
{
return providers.keySet();
}
private String periodType;
private String expression;
/**
* Create a period without an accompanying expression.
*
* @param period
*/
public Period(String period)
{
String[] parts = period.split("\\|", 2);
periodType = parts[0];
if (parts.length == 2)
{
expression = parts[1];
}
}
/**
* Calculate the next date for this period given the a start date.
*
* @param date
* @return the next date.
*/
public Date getNextDate(Date date)
{
PeriodProvider provider = getProvider(periodType);
return provider.getNextDate(date, expression != null ? expression : provider.getDefaultExpression());
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((expression == null) ? 0 : expression.hashCode());
result = prime * result + ((periodType == null) ? 0 : periodType.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Period other = (Period) obj;
if (expression == null)
{
if (other.expression != null)
return false;
}
else if (!expression.equals(other.expression))
return false;
if (periodType == null)
{
if (other.periodType != null)
return false;
}
else if (!periodType.equals(other.periodType))
return false;
return true;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append(periodType);
if (expression != null)
{
builder.append("|");
builder.append(expression);
}
return builder.toString();
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.repository;
import java.util.Date;
/**
* Provider API for period implementations
* @author andyh
*
*/
public interface PeriodProvider
{
/**
* Period expression multiplicity
* @author andyh
*
*/
public enum ExpressionMutiplicity
{
/**
* There is no expression
*/
NONE,
/**
* An expression is optional
*/
OPTIONAL,
/**
* An expression is mandatory
*/
MANDATORY
}
/**
* Get the name for the period.
* @return - period name
*/
public String getPeriodType();
/**
* Get the next date - the provided date + period
* @param date
* @param expression
* @return the next date in the period
*/
public Date getNextDate(Date date, String expression);
/**
* Is the expression required etc ...
* @return the multiplicity
*/
public ExpressionMutiplicity getExpressionMutiplicity();
/**
* Get the default expression - this could be null
* @return - the default expression.
*/
public String getDefaultExpression();
}

View File

@@ -53,6 +53,7 @@ import org.alfresco.service.cmr.repository.EntityRef;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.Period;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ISO8601DateFormat;
import org.alfresco.util.VersionNumber;
@@ -291,6 +292,14 @@ public class DefaultTypeConverter
}
});
INSTANCE.addConverter(String.class, Period.class, new TypeConverter.Converter<String, Period>()
{
public Period convert(String source)
{
return new Period(source);
}
});
INSTANCE.addConverter(String.class, VersionNumber.class, new TypeConverter.Converter<String, VersionNumber>()
{
public VersionNumber convert(String source)
@@ -399,6 +408,15 @@ public class DefaultTypeConverter
}
});
// From Period
INSTANCE.addConverter(Period.class, String.class, new TypeConverter.Converter<Period, String>()
{
public String convert(Period source)
{
return source.toString();
}
});
//
// Number to Subtypes and Date

View File

@@ -39,6 +39,7 @@ import org.alfresco.repo.attributes.MapAttributeValue;
import org.alfresco.repo.attributes.StringAttribute;
import org.alfresco.repo.attributes.StringAttributeValue;
import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.Period;
import org.alfresco.util.ISO8601DateFormat;
import org.alfresco.util.VersionNumber;
@@ -113,6 +114,9 @@ public class DefaultTypeConverterTest extends TestCase
assertEquals("fr_FR_", DefaultTypeConverter.INSTANCE.convert(String.class, Locale.FRANCE));
// VersionNumber
assertEquals("1.2.3", DefaultTypeConverter.INSTANCE.convert(String.class, new VersionNumber("1.2.3")));
// Period
assertEquals("period", DefaultTypeConverter.INSTANCE.convert(String.class, new Period("period")));
assertEquals("period|12", DefaultTypeConverter.INSTANCE.convert(String.class, new Period("period|12")));
}
public void testFromString()
@@ -148,6 +152,9 @@ public class DefaultTypeConverterTest extends TestCase
assertEquals(Locale.FRANCE, DefaultTypeConverter.INSTANCE.convert(Locale.class, "fr_FR_"));
assertEquals(new VersionNumber("1.2.3"), DefaultTypeConverter.INSTANCE.convert(VersionNumber.class, "1.2.3"));
assertEquals(new Period("period"), DefaultTypeConverter.INSTANCE.convert(Period.class, "period"));
assertEquals(new Period("period|12"), DefaultTypeConverter.INSTANCE.convert(Period.class, "period|12"));
}
String localeStrEn = DefaultTypeConverter.INSTANCE.convert(String.class, Locale.ENGLISH);