diff --git a/src/java/com/samskivert/depot/Transformer.java b/src/java/com/samskivert/depot/Transformer.java new file mode 100644 index 0000000..eb0fa2a --- /dev/null +++ b/src/java/com/samskivert/depot/Transformer.java @@ -0,0 +1,38 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2010 Michael Bayne and Pär Winzell +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.depot; + +/** + * Transforms a persistent record field into a format that can be read and written by the + * underlying database. For example, one might transform an enum into a byte, short or integer. Or + * one might transform a string array into a single string, using a separator known to be + * appropriate for the contents. + * + * @see Transformers + */ +public interface Transformer +{ + /** Transforms a runtime value into a value that can be persisted. */ + T toPersistent (F value); + + /** Transforms a persisted value into a value that can be store in a runtime field. */ + F fromPersistent (T value); +} diff --git a/src/java/com/samskivert/depot/Transformers.java b/src/java/com/samskivert/depot/Transformers.java new file mode 100644 index 0000000..0238bbb --- /dev/null +++ b/src/java/com/samskivert/depot/Transformers.java @@ -0,0 +1,53 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2010 Michael Bayne and Pär Winzell +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.depot; + +import com.google.common.base.Joiner; + +import com.samskivert.depot.annotation.Column; + +/** + * Contains various generally useful {@link Transformer} implementations. To use a transformer, you + * specify it via a {@link Column} annotation. For example: + *
+ * public class MyRecord extends PersistentRecord {
+ *     @Transform(Transformers.CommaSeparatedString.class)
+ *     public String[] cities;
+ * }
+ * 
+ * Because of limitations of Java's annotation system, configuration of transformers is not + * possible (without complex machinations) and separate classes must be created for any particular + * transformation. + */ +public class Transformers +{ + /** + * Combines the contents of a String[] column into a single string, separated by commas. + */ + public static class CommaSeparatedString implements Transformer { + public String toPersistent (String[] value) { + return Joiner.on(",").join(value); + } + public String[] fromPersistent (String value) { + return value.split(","); + } + } +} diff --git a/src/java/com/samskivert/depot/annotation/Transform.java b/src/java/com/samskivert/depot/annotation/Transform.java new file mode 100644 index 0000000..9e47366 --- /dev/null +++ b/src/java/com/samskivert/depot/annotation/Transform.java @@ -0,0 +1,69 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2010 Michael Bayne and Pär Winzell +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.depot.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.samskivert.depot.Transformer; + +/** + * Declares that the target of this annotation, either a field in a {@link PersistentRecord} or a + * type (which will eventually be stored in a persistent record), should be transformed before + * saving to the database and after loading from the database. + * + *

For example, one may choose to transform a particular persistent record field into a type + * supported directly by Depot: + * + *

+ * public class MyRecord extends PersistentRecord {
+ *     @Transform(Transformers.CommaSeparatedString.class)
+ *     public String[] cities;
+ * }
+ * 
+ * + * or one may opt to specify a transformation for all fields that contain a value of a particular + * type: + * + *
+ * @Transform(ByteEnumTransformer.class)
+ * public interface ByteEnum { ... }
+ * 
+ * + * Note that because Depot honors @Transform annotations on any interface implemented by a type, or + * on a type's superclass, it is possible that conflicting transformations may be specified. In + * this case, Depot will fail with a runtime error during initialization, to indicate the problem. + * + * @see Transformer + */ +@Target(value={ElementType.TYPE, ElementType.FIELD}) +@Retention(value=RetentionPolicy.RUNTIME) +@Inherited +public @interface Transform +{ + /** + * Specifies a transformer to be used when persisting the target of this annotation. + */ + Class value (); +}