era-cvs_traffic Mailing List for Enterprise Reporting Architecture
Brought to you by:
jessex
You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(48) |
Aug
(54) |
Sep
(28) |
Oct
(12) |
Nov
(20) |
Dec
(34) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(27) |
Feb
(10) |
Mar
(7) |
Apr
(15) |
May
|
Jun
(21) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(15) |
Jun
(72) |
Jul
(5) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(6) |
Aug
|
Sep
|
Oct
(14) |
Nov
|
Dec
|
|
From: <je...@23...> - 2008-10-06 11:30:00
|
Update of /cvsroot/era/src/org/jdaemon/util/expression In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12394/expression Log Message: Directory /cvsroot/era/src/org/jdaemon/util/expression added to the repository |
|
From: <je...@23...> - 2008-10-06 10:26:36
|
Update of /cvsroot/era/src/org/jdaemon/test/util/attribute In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/test/util/attribute Added Files: TestAttributePackage.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' --- NEW FILE: TestAttributePackage.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.test.util.attribute; import org.jdaemon.util.attribute.*; import org.jdaemon.util.functional.*; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.util.LinkedList; import java.util.List; /** Test class for Attributes. * * This is a Test container for attributes. str_attr and int_attr are two test attributes which * address values of stringv and intv respectively. * * @author jonathan */ class TestObject { public String stringv; public Integer intv; public TestObject(String a, Integer i) { stringv = a; intv = i; } /** The accessor object for stringv. * * Subclasses ComparableAttribute, which provides requires that the value type * is comparable. Otherwise we would have to implemnet getComparator() ourselves. * */ public static Attribute<String,TestObject> str_attr = new ComparableAttribute<String,TestObject>() { /** Return the value of member stringv in an instance of TestObject. * * @param o An instance of TestObject * @return the value of member variable stringv in o */ public String getValue(TestObject o) { return o.stringv; } /** Set the value of member stringv in an instance of TestObject. * * @param o An instance of TestObject * @param s a new value for the member variable stringv in o */ public void setValue(String s, TestObject o) { o.stringv = s; } }; /** The accessor object for intv. * * Subclasses ComparableAttribute, which provides requires that the value type * is comparable. Otherwise we would have to implement getComparator() ourselves. * */ public static NumericAttribute<Integer, TestObject> int_attr = new NumericAttribute<Integer,TestObject>() { /** Return the value of member stringv in an instance of TestObject. * * @param o An instance of TestObject * @return the value of member variable intv in o */ public Integer getValue(TestObject o) { return o.intv; } /** Set the value of member intv in an instance of TestObject. * * @param o An instance of TestObject * @param i a new value for the member variable intv in o */ public void setValue(Integer i, TestObject o) { o.intv = i; } }; } /** Test cases for the Attribute package. * * We define a class (TestObject) and two attributes int_attr and string_attr, and * perform various test operations thereon. * * @author jonathan */ public class TestAttributePackage extends TestCase { /** Create a list full of TestObjects. * * @return a list of test data. All data fields are defined. */ private LinkedList<TestObject> newTestList() { LinkedList<TestObject> result = new LinkedList<TestObject>(); result.add(new TestObject("one", 1)); result.add(new TestObject("two", 2)); result.add(new TestObject("three", 3)); result.add(new TestObject("four", 4)); result.add(new TestObject("five", 5)); result.add(new TestObject("six", 6)); result.add(new TestObject("seven", 7)); result.add(new TestObject("eight", 8)); return result; } /** Create a list full of TestObjects. * * @return a list of test data. Some data fields are null. */ private LinkedList<TestObject> newTestListWithNulls() { LinkedList<TestObject> list = newTestList(); list.addFirst(new TestObject("nullint",null)); list.addLast(new TestObject(null, new Integer(9))); list.add(4,new TestObject(null,null)); return list; } /** Tests getting the value of intv out of a TestObject using an attribute. */ public void testGetAttributeInt() { TestObject o = new TestObject("one",1); assertEquals(new Integer(1), TestObject.int_attr.getValue(o)); } /** Tests getting the value of stringv out of a TestObject using an attribute. */ public void testGetAttributeString() { TestObject o = new TestObject("one",1); assertEquals("one", TestObject.str_attr.getValue(o)); } /** Tests setting the value of intv in a TestObject using an attribute. */ public void testSetAttributeInt() { TestObject o = new TestObject("one",2); TestObject.int_attr.setValue(1,o); assertEquals(new Integer(1), TestObject.int_attr.getValue(o)); } /** Tests setting the value of stringv in a TestObject using an attribute. */ public void testSetAttributeString() { TestObject o = new TestObject("two",1); TestObject.str_attr.setValue("one",o); assertEquals("one", TestObject.str_attr.getValue(o)); } /** Tests the use of the Attributes.max function on string and integer attributes */ public void testMax() { LinkedList<TestObject> list = newTestList(); assertEquals(new Integer(8), Attributes.max(list, TestObject.int_attr)); assertEquals("two", Attributes.max(list, TestObject.str_attr)); } /** Tests the use of the Attributes.max function on string and integer attributes */ public void testMaxWithNulls() { LinkedList<TestObject> list = newTestListWithNulls(); assertEquals(new Integer(9), Attributes.max(list, TestObject.int_attr)); assertEquals("two", Attributes.max(list, TestObject.str_attr)); } /** Tests the use of the Attributes.min function on string and integer attributes */ public void testMin() { LinkedList<TestObject> list = newTestList(); assertEquals(new Integer(1), Attributes.min(list, TestObject.int_attr)); assertEquals("eight", Attributes.min(list, TestObject.str_attr)); } /** Tests the use of the Attributes.min function on string and integer attributes. * * Note: This is where we have to start thinking. If values can be null, we want * the min function to return the lowest non-null value. However, if we are sorting * a list, the null values should be treated as 'lowest'. */ public void testMinWithNulls() { LinkedList<TestObject> list = newTestListWithNulls(); assertEquals(new Integer(1), Attributes.min(list, TestObject.int_attr)); assertEquals("eight", Attributes.min(list, TestObject.str_attr)); } /** Tests the use of the Attributes.count function on string and integer attributes */ public void testCount() { LinkedList<TestObject> list = newTestList(); assertEquals(8, Attributes.count(list, TestObject.int_attr)); assertEquals(8, Attributes.count(list, TestObject.str_attr)); } public void testSort() { LinkedList<TestObject> list = newTestList(); Attributes.sort(list, TestObject.str_attr); assertEquals(list.getFirst().intv, new Integer(8)); assertEquals(list.getLast().intv, new Integer(2)); } private void doTestAggregates(LinkedList<TestObject> list) { Accumulator<TestObject,String> max_str = TestObject.str_attr.newMax(); Accumulator<TestObject,String> min_str = TestObject.str_attr.newMin(); Accumulator<TestObject,Long> count_str = TestObject.str_attr.newCount(); Accumulator<TestObject,Number> sum_int = TestObject.int_attr.newSum(); LinkedList<Accumulator<TestObject,?>> aggs = new LinkedList<Accumulator<TestObject,?>>(); aggs.add(max_str); aggs.add(min_str); aggs.add(count_str); aggs.add(sum_int); Attributes.aggregates(list, aggs); assertEquals(max_str.getResult(), Attributes.max(list, TestObject.str_attr)); assertEquals(min_str.getResult(), Attributes.min(list, TestObject.str_attr)); // figure out what the count and sum are supposed to be long count = 0; double sum = 0; for (TestObject o : list) { if (o.stringv != null) count++; if (o.intv != null) sum+=o.intv.doubleValue(); } assertEquals(count_str.getResult(), new Long(count)); assertEquals(sum_int.getResult(), new Double(sum)); } public void testAggregates() { doTestAggregates(newTestList()); } public void testAggregatesWithNulls() { doTestAggregates(newTestListWithNulls()); } public void testFilter() { LinkedList<TestObject> test = newTestList(); List<TestObject> result; result = Operations.filter(test, TestObject.int_attr.isLessThan(4)); assertEquals(result.size(), 3); result = Operations.filter(test, TestObject.int_attr.isGreaterThan(6)); assertEquals(result.size(), 2); // expand this. } public static TestSuite suite() { return new TestSuite(TestAttributePackage.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } } |
|
From: <je...@23...> - 2008-10-06 10:25:14
|
Update of /cvsroot/era/src/org/jdaemon/test/util In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12462/util Log Message: Directory /cvsroot/era/src/org/jdaemon/test/util added to the repository |
|
From: <je...@23...> - 2008-10-06 10:24:56
|
Update of /cvsroot/era/src/org/jdaemon/test/util/functional In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/test/util/functional Added Files: TestFunctionalPackage.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' --- NEW FILE: TestFunctionalPackage.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.test.util.functional; import org.jdaemon.util.functional.*; import org.jdaemon.util.expression.*; import java.util.LinkedList; import java.util.TreeSet; import java.util.List; import java.util.Set; import java.util.Iterator; import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** Test class for multi-way accumulator * * @author jonathan */ class TestObject { public String stringv; public Integer intv; public TestObject(String a, Integer i) { stringv = a; intv = i; } public static UnaryFunction<TestObject, String> str_a = new AbstractUnaryFunction<TestObject, String>() { public String operate(TestObject t) { return t.stringv; } }; public static UnaryFunction<TestObject, Integer> int_a = new AbstractUnaryFunction<TestObject, Integer>() { public Integer operate(TestObject t) { return t.intv; } }; } /** * * @author jonathan */ public class TestFunctionalPackage extends TestCase { public static final UnaryFunction<Integer,Integer> plusone = new AbstractUnaryFunction<Integer,Integer>() { public Integer operate(Integer a) { return a + 1; } }; public static final BinaryFunction<Integer,Integer,Integer> plus = new AbstractBinaryFunction<Integer,Integer,Integer>() { public Integer operate(Integer a, Integer b) { return a + b; } }; public void testPlusOne() { assertEquals(plusone.operate(0),new Integer(1)); } public void testPlus() { assertEquals(plus.operate(2,2),new Integer(4)); } public void testChain() { assertEquals(Operations.Chain(plusone,plusone).operate(0), new Integer(2)); assertEquals(Operations.Chain(plus,plusone).operate(2,2), new Integer(5)); } public void testSum() { SumFunction<Integer> sum = new SumFunction<Integer>(); Number total = new Double(0.0); total = sum.operate(total,1); total = sum.operate(total,2); assertEquals(total, new Double(3.0)); } public void testCount() { CountFunction<String> count = new CountFunction<String>(); Long total = 0L; total = count.operate(total, "Hello"); total = count.operate(total, null); assertEquals(total, new Long(1)); } public void testMin() { MinFunction<String> min = new MinFunction<String>(String.CASE_INSENSITIVE_ORDER); assertEquals(min.operate("abc","def"), "abc"); } public void testMax() { MaxFunction<String> max = new MaxFunction<String>(String.CASE_INSENSITIVE_ORDER); assertEquals(max.operate("abc","def"), "def"); } private static UnaryFunction<Integer, Boolean> lessthanfive = new AbstractUnaryFunction<Integer,Boolean>() { public Boolean operate(Integer i) { return i < 5; } }; public void testFilterCollection() { Set<Integer> test = new TreeSet<Integer>(); test.add(1); test.add(3); test.add(2); test.add(7); test.add(5); Iterator<Integer> res = Operations.filter(test, lessthanfive).iterator(); assertEquals(res.next().intValue(), 1); assertEquals(res.next().intValue(), 2); assertEquals(res.next().intValue(), 3); assertEquals(res.hasNext(), false); } public void testFilterList() { List<Integer> test = new LinkedList<Integer>(); test.add(1); test.add(3); test.add(7); test.add(2); test.add(5); List<Integer> res = Operations.filter(test, lessthanfive); assertEquals(res.get(0).intValue(), 1); assertEquals(res.get(1).intValue(), 3); assertEquals(res.get(2).intValue(), 2); } public void testSizeFilterList() { List<Integer> test = new LinkedList<Integer>(); test.add(1); test.add(3); test.add(7); test.add(2); test.add(5); List<Integer> res = Operations.filter(test, lessthanfive); assertEquals(res.size(), 3); } //Not a good test, but it's here to document that this usage pattern is going to be important public void testMultipleAccumulation() { BinaryFunction<Number,Integer,Number> sum = new SumFunction<Integer>(); BinaryFunction<String, String, String> max = new MaxFunction<String>(String.CASE_INSENSITIVE_ORDER); BinaryFunction<Number,TestObject,Number> sum_int_a = Operations.ChainSecond(TestObject.int_a, sum); BinaryFunction<String,TestObject,String> max_str_a = Operations.ChainSecond(TestObject.str_a, max); FunctionAccumulator<TestObject, ? extends Object> a1 = new FunctionAccumulator<TestObject, Number>(0.0, sum_int_a); FunctionAccumulator<TestObject, ? extends Object> a2 = new FunctionAccumulator<TestObject, String>("", max_str_a); TestObject t1 = new TestObject("abcc", 27); TestObject t2 = new TestObject("def", 2); a1.accumulate(t1); a2.accumulate(t1); a1.accumulate(t2); a2.accumulate(t2); } public <T> void doTestArithmetic(final ArithmeticOperations<T> o) { BinaryFunction<T,T,T> add = o.Add(o.parameter,o.parameter); BinaryFunction<T,T,T> mul = o.Mul(o.parameter,o.parameter); BinaryFunction<T,T,T> div = o.Div(o.parameter,o.parameter); BinaryFunction<T,T,T> sub = o.Sub(o.parameter,o.parameter); T zero = o.arithmetic.zero(); T one = o.arithmetic.one(); T two = o.arithmetic.add(one, one); T four = o.arithmetic.add(two, two); assertEquals(add.operate(one,one), two); assertEquals(add.operate(one,zero), one); assertEquals(sub.operate(two,one), one); assertEquals(sub.operate(two,zero), two); assertEquals(mul.operate(two,one), two); assertEquals(mul.operate(two,zero),zero); assertEquals(mul.operate(two,two), four); assertEquals(div.operate(two,one), two); assertEquals(div.operate(two,two), one); assertEquals(div.operate(four,two), two); } public void testArithmetic() { doTestArithmetic(Operations.DOUBLE); doTestArithmetic(Operations.FLOAT); doTestArithmetic(Operations.LONG); doTestArithmetic(Operations.INTEGER); } public void testComparisons() { Integer one = new Integer(1); Integer two = new Integer(2); BinaryFunction<Integer,Integer,Boolean> eq = Operations.EQ(Parameter.INTEGER, Parameter.INTEGER); BinaryFunction<Integer,Integer,Boolean> lt = Operations.LT(Parameter.INTEGER, Parameter.INTEGER); BinaryFunction<Integer,Integer,Boolean> gt = Operations.GT(Parameter.INTEGER, Parameter.INTEGER); BinaryFunction<Integer,Integer,Boolean> lte = Operations.LTE(Parameter.INTEGER, Parameter.INTEGER); BinaryFunction<Integer,Integer,Boolean> gte = Operations.GTE(Parameter.INTEGER, Parameter.INTEGER); assertTrue(eq.operate(one, one)); assertFalse(eq.operate(one, two)); assertTrue(lt.operate(one, two)); assertFalse(lt.operate(two, one)); assertFalse(lt.operate(one, one)); assertTrue(gt.operate(two, one)); assertFalse(gt.operate(one, two)); assertFalse(gt.operate(one, one)); assertTrue(lte.operate(one, two)); assertFalse(lte.operate(two, one)); assertTrue(lte.operate(one, one)); assertTrue(gte.operate(two, one)); assertFalse(gte.operate(one, two)); assertTrue(gte.operate(one, one)); } public void testExpression() throws OutputError { BinaryFunction<Integer, Integer, Boolean> test_expr = Operations.GT(Parameter.INTEGER, Operations.INTEGER.Add(Parameter.INTEGER, 1)); StringWriter out = new StringWriter(); test_expr.write(new SimpleExpressionWriter(out)); assertFalse(test_expr.operate(1, 8)); assertTrue(test_expr.operate(8, 1)); assertFalse(test_expr.operate(7, 8)); assertFalse(test_expr.operate(8, 7)); assertEquals("a>a+1", out.toString()); } public void testBooleanExpression() throws OutputError { BinaryFunction<Integer, Integer, Boolean> test_expr = Operations.AND( Operations.GT( 4, Operations.INTEGER.Add(Parameter.INTEGER, 1)), Operations.LT( 3, Parameter.INTEGER)); StringWriter out = new StringWriter(); test_expr.write(new SimpleExpressionWriter(out)); System.out.println(out.toString()); assertTrue(test_expr.operate(2, 4)); assertFalse(test_expr.operate(3, 4)); assertFalse(test_expr.operate(2, 3)); assertFalse(test_expr.operate(3, 3)); } public static TestSuite suite() { return new TestSuite(TestFunctionalPackage.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } } |
|
From: <je...@23...> - 2008-10-06 10:23:16
|
Update of /cvsroot/era/src/org/jdaemon/test/util/expression In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/test/util/expression Added Files: TestExpressionPackage.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' --- NEW FILE: TestExpressionPackage.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.test.util.expression; import org.jdaemon.util.expression.*; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.io.StringWriter; import java.util.HashMap; import java.util.HashSet; /** * * @author jonathan */ public class TestExpressionPackage extends TestCase { public static String getOperatorPrecedenceTestResult(Expression.Type inner, Expression.Type outer, boolean brackets) { StringWriter res = new StringWriter(); if (brackets) res.append("("); res.append("27"); res.append(SimpleExpressionWriter.DEFAULT_STRING_MAP.get(inner)); res.append("19"); if (brackets) res.append(")"); res.append(SimpleExpressionWriter.DEFAULT_STRING_MAP.get(outer)); res.append("3"); return res.toString(); } public static void doTestOperatorPrecedence(Expression.Type inner, Expression.Type outer, boolean brackets) throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); writer.beginExpression(outer); writer.beginExpression(inner); writer.writeValue((Integer)27); writer.writeValue((Integer)19); writer.endExpression(inner); writer.writeValue((Integer)3); writer.endExpression(outer); assertEquals(res.toString(), getOperatorPrecedenceTestResult(inner, outer, brackets)); } public void testOperatorPrecedence() throws OutputError { doTestOperatorPrecedence(Expression.Type.ADD, Expression.Type.MUL, true); doTestOperatorPrecedence(Expression.Type.MUL, Expression.Type.ADD, false); doTestOperatorPrecedence(Expression.Type.ADD, Expression.Type.DIV, true); doTestOperatorPrecedence(Expression.Type.DIV, Expression.Type.ADD, false); doTestOperatorPrecedence(Expression.Type.DIV, Expression.Type.MUL, false); doTestOperatorPrecedence(Expression.Type.MUL, Expression.Type.DIV, true); doTestOperatorPrecedence(Expression.Type.ADD, Expression.Type.SUB, false); doTestOperatorPrecedence(Expression.Type.SUB, Expression.Type.ADD, true); } public static String getComparisonTestResult(Expression.Type comp) { StringWriter res = new StringWriter(); res.write("12"); res.write(SimpleExpressionWriter.DEFAULT_STRING_MAP.get(comp)); res.write("13"); return res.toString(); } public static void doTestComparison(Expression.Type comp) throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); writer.beginExpression(comp); writer.writeValue("12"); writer.writeValue("13"); writer.endExpression(comp); assertEquals(res.toString(), getComparisonTestResult(comp)); } public void testComparison() throws OutputError { doTestComparison(Expression.Type.EQ); doTestComparison(Expression.Type.LT); doTestComparison(Expression.Type.GT); doTestComparison(Expression.Type.GTE); doTestComparison(Expression.Type.LTE); } public void writeComplexExpression(ExpressionWriter writer) throws OutputError { writer.beginExpression(Expression.Type.OR); writer.beginExpression(Expression.Type.AND); writer.beginExpression(Expression.Type.LT); writer.writeValue("13"); writer.writeValue("11"); writer.endExpression(Expression.Type.LT); writer.beginExpression(Expression.Type.GT); writer.writeValue("99"); writer.writeValue("34"); writer.endExpression(Expression.Type.GT); writer.endExpression(Expression.Type.AND); writer.beginExpression(Expression.Type.AND); writer.beginExpression(Expression.Type.EQ); writer.writeValue("8"); writer.writeValue("7"); writer.endExpression(Expression.Type.EQ); writer.beginExpression(Expression.Type.NOT); writer.beginExpression(Expression.Type.GT); writer.writeValue("99"); writer.writeValue("34"); writer.endExpression(Expression.Type.GT); writer.endExpression(Expression.Type.NOT); writer.endExpression(Expression.Type.AND); writer.endExpression(Expression.Type.OR); } public void testComplexExpression() throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); writeComplexExpression(writer); assertEquals(res.toString(),"13<11 && 99>34 || 8=7 && !(99>34)"); } public void testMultipleAdd() throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); writer.beginExpression(Expression.Type.ADD); writer.writeValue((Integer)19); writer.beginExpression(Expression.Type.ADD); writer.writeValue((Integer)20); writer.writeValue((Integer)21); writer.endExpression(Expression.Type.ADD); writer.endExpression(Expression.Type.ADD); assertEquals(res.toString(), "19+20+21"); } public void testUserFunc() throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); writer.beginExpression(Expression.Type.FUNC); writer.writeValue("maximum"); writer.writeValue((Integer)21); writer.writeValue((Integer)12); writer.endExpression(Expression.Type.FUNC); assertEquals(res.toString(), "maximum(21,12)"); } public void doWriteParameterisedExpression(ExpressionWriter writer) throws OutputError { writer.beginExpression(Expression.Type.ADD); writer.writeParameter("one"); writer.beginExpression(Expression.Type.MUL); writer.writeValue("value"); writer.writeParameter("two"); writer.endExpression(Expression.Type.MUL); writer.endExpression(Expression.Type.ADD); } public void testUnboundParameters() throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); doWriteParameterisedExpression(writer); assertEquals(res.toString(), "one+value*two"); } public void testParametrisation() throws OutputError { StringWriter res = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(res); writer = Expressions.bindParameter(writer, "First", 1); writer = Expressions.bindParameter(writer, "Second",2); doWriteParameterisedExpression(writer); assertEquals(res.toString(), "First+value*Second"); } public void testCustomisation() throws OutputError { HashMap<Expression.Type, String> string_mappings = new HashMap<Expression.Type,String>(SimpleExpressionWriter.DEFAULT_STRING_MAP); HashSet<Expression.Type> infix_set = new HashSet<Expression.Type>(SimpleExpressionWriter.DEFAULT_INFIX_SET); HashSet<Expression.Type> prefix_set = new HashSet<Expression.Type>(SimpleExpressionWriter.DEFAULT_PREFIX_SET); // Modify mappings by swapping &&, ||, ! for AND OR and NOT string_mappings.put(Expression.Type.AND, "AND"); string_mappings.put(Expression.Type.OR, "OR"); string_mappings.put(Expression.Type.NOT, "NOT"); // Remove AND and OR operators from infix set infix_set.remove(Expression.Type.AND); infix_set.remove(Expression.Type.OR); // Remove NOT operator from prefix set prefix_set.remove(Expression.Type.NOT); StringWriter out = new StringWriter(); ExpressionWriter writer = new SimpleExpressionWriter(out, string_mappings, infix_set, prefix_set); writeComplexExpression(writer); assertEquals(out.toString(), "OR(AND(13<11,99>34),AND(8=7,NOT(99>34)))"); } public static TestSuite suite() { return new TestSuite(TestExpressionPackage.class); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } } |
|
From: <je...@23...> - 2008-10-06 10:23:16
|
Update of /cvsroot/era/src/org/jdaemon/util/expression In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/util/expression Added Files: DelegatingExpressionWriter.java Expression.java ExpressionWriter.java Expressions.java OutputError.java SimpleExpressionWriter.java ValueExpression.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' --- NEW FILE: DelegatingExpressionWriter.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; import org.jdaemon.util.expression.Expression.Type; /** * * @author jonathan */ class DelegatingExpressionWriter implements ExpressionWriter { protected ExpressionWriter parent; public <T> void writeValue(T value) throws OutputError { parent.writeValue(value); } public void writeParameter(String name) throws OutputError { parent.writeParameter(name); } public void beginExpression(Type type) throws OutputError { parent.beginExpression(type); } public void endExpression(Type type) throws OutputError { parent.endExpression(type); } public DelegatingExpressionWriter(ExpressionWriter parent) { this.parent = parent; } } --- NEW FILE: Expression.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; /** * * @author jonathan */ public interface Expression { public enum Type { ADD, SUB, MUL, DIV, EQ, LT, GT, LTE, GTE, AND, OR, NOT, PARAM, VALUE, FUNC } public void write(ExpressionWriter out) throws OutputError; } --- NEW FILE: ExpressionWriter.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; /** ExpressionWriter provices a mechanism for processing expressions. * * The convention is that an expression object will write its sub-expressions * and values before writing its own type. * * For example, an expression 1 + 2 should be written this: * * writer.writeValue(1); * writer.writeValue(2); * writer.endExpression(Expression.Type.ADD); * * @author jonathan */ public interface ExpressionWriter { /** Push a value. * * @param value to push. */ public <T> void writeValue(T value) throws OutputError; /** Push a parameter. * * @param value to push. */ public void writeParameter(String name) throws OutputError; /** Push a value. * * @param value to push. */ public void beginExpression(Expression.Type type) throws OutputError; /** Push a value. * * @param value to push. */ public void endExpression(Expression.Type type) throws OutputError; } --- NEW FILE: Expressions.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; /** * * @author jonathan */ public class Expressions { private static class ParameterBinder extends DelegatingExpressionWriter { private int index; private Expression bound; public ParameterBinder(ExpressionWriter writer, Expression bound, int index) { super(writer); this.index = index; this.bound = bound; } /** Output bound expression or pass on unbound parameter up delegation chain. * * @param name * @throws org.jdaemon.util.expression.OutputError */ public void writeParameter(String name) throws OutputError { index--; if (index == 0) bound.write(parent); else parent.writeParameter(name); } } public static ExpressionWriter bindParameter(ExpressionWriter writer, Expression value) { return new ParameterBinder(writer, value, 1); } public static ExpressionWriter bindParameter(ExpressionWriter writer, Expression value, int index) { return new ParameterBinder(writer, value, index); } public static <T> ExpressionWriter bindParameter(ExpressionWriter writer, T value) { return bindParameter(writer, new ValueExpression<T>(value)); } public static <T> ExpressionWriter bindParameter(ExpressionWriter writer, T value, int index) { return bindParameter(writer, new ValueExpression<T>(value), index); } } --- NEW FILE: OutputError.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; /** * * @author jonathan */ public class OutputError extends Exception { /** * Creates a new instance of <code>OutputError</code> without detail message. */ public OutputError() { } /** * Constructs an instance of <code>OutputError</code> with the specified detail message. * @param msg the detail message. */ public OutputError(String msg) { super(msg); } } --- NEW FILE: SimpleExpressionWriter.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; import java.io.IOException; import java.util.Stack; import java.io.Writer; import java.util.LinkedList; import java.util.Iterator; import java.util.Map; import java.util.HashMap; import java.util.Collections; import java.util.Set; import java.util.HashSet; /** ExpressionWriter that outputs 'natural' expression to a writer. * * * * * @author jonathan */ public class SimpleExpressionWriter implements ExpressionWriter { /** Private base class for all types of expression. * * YES, it has a public data member. */ private static abstract class Node { /** Type of node. */ public final Expression.Type type; /** Construct a node of given type. * * Note type of node cannot be changed after creation. * * @param type Type of node. */ public Node(Expression.Type type) { this.type = type; } } /** Subclass of Node representing a complex expression. * */ private static class ExpressionNode extends Node { public final LinkedList<Node> children = new LinkedList<Node>(); public ExpressionNode(Expression.Type type) { super(type); } } private static class ValueNode<T> extends Node { public final T value; public ValueNode(Expression.Type type, T value) { super(type); this.value = value; } } private static Map<Expression.Type, String> initDefaultOperators() { HashMap<Expression.Type,String> operators = new HashMap<Expression.Type, String>(); operators.put(Expression.Type.ADD, "+"); operators.put(Expression.Type.AND, " && "); operators.put(Expression.Type.DIV, "/"); operators.put(Expression.Type.EQ, "="); operators.put(Expression.Type.GT, ">"); operators.put(Expression.Type.GTE, ">="); operators.put(Expression.Type.LT, "<"); operators.put(Expression.Type.LTE, "<="); operators.put(Expression.Type.MUL, "*"); operators.put(Expression.Type.NOT, "!"); operators.put(Expression.Type.OR, " || "); operators.put(Expression.Type.SUB, "-"); return Collections.unmodifiableMap(operators); } private static Set<Expression.Type> initInfixOperators() { HashSet<Expression.Type> operators = new HashSet<Expression.Type>(); operators.add(Expression.Type.ADD); operators.add(Expression.Type.AND); operators.add(Expression.Type.DIV); operators.add(Expression.Type.EQ); operators.add(Expression.Type.GT); operators.add(Expression.Type.GTE); operators.add(Expression.Type.LT); operators.add(Expression.Type.LTE); operators.add(Expression.Type.MUL); operators.add(Expression.Type.OR); operators.add(Expression.Type.SUB); return Collections.unmodifiableSet(operators); } private static Set<Expression.Type> initPrefixOperators() { HashSet<Expression.Type> operators = new HashSet<Expression.Type>(); operators.add(Expression.Type.NOT); return Collections.unmodifiableSet(operators); } public static final Map<Expression.Type, String> DEFAULT_STRING_MAP = initDefaultOperators(); public static final Set<Expression.Type> DEFAULT_INFIX_SET = initInfixOperators(); public static final Set<Expression.Type> DEFAULT_PREFIX_SET = initPrefixOperators(); private Writer out; private Stack<ExpressionNode> stack = new Stack<ExpressionNode>(); private ExpressionNode top = null; private Map<Expression.Type, String> operators; private Set<Expression.Type> prefix_operators; private Set<Expression.Type> infix_operators; /** Output a child expression, bracketed as necessary. * * We must insert brackets in order to preserve the evaluation order specified by the original expression. * We supress the bracketing of the child expression in three cases: * * 1) the child expression is a value * 2) the child expression is an operation with a priority greater than the parent expression (BODMASS) * 3) the child expression and parent expression have the same operator, and the operation is associative * * @param parent * @param child * @throws java.io.IOException */ private void outputChildExpression(ExpressionNode parent, Node child) throws IOException, OutputError { if (parent.type == child.type && isAssociative(parent.type) || getPriority(parent.type) < getPriority(child.type)) { outputExpression(child); } else { out.write("("); outputExpression(child); out.write(")"); } } private void outputPrefixExpression(ExpressionNode expression) throws IOException, OutputError { out.write(operators.get(expression.type)); outputChildExpression(expression, expression.children.getFirst()); } private void outputInfixExpression(ExpressionNode expression) throws IOException, OutputError { if(expression.children.size() != 2) throw new OutputError("Infix expression must have two parameters"); outputChildExpression(expression, expression.children.getFirst()); out.write(operators.get(expression.type)); outputChildExpression(expression, expression.children.getLast()); } private void outputPostfixExpression(ExpressionNode expression) throws IOException, OutputError { out.write(operators.get(expression.type)); out.write("("); Iterator<Node> params = expression.children.iterator(); if (params.hasNext()) { outputExpression(params.next()); while(params.hasNext()) { out.write(","); outputExpression(params.next()); } } out.write(")"); } private void outputExpression(Node expression) throws IOException, OutputError { switch (expression.type) { case PARAM: case VALUE: outputValueExpression((ValueNode<?>)expression); break; case FUNC: outputFunctionExpression((ExpressionNode)expression); break; default: if (infix_operators.contains(expression.type)) outputInfixExpression((ExpressionNode)expression); else if (prefix_operators.contains(expression.type)) outputPrefixExpression((ExpressionNode)expression); else outputPostfixExpression((ExpressionNode)expression); } } private void outputValueExpression(ValueNode<?> expression) throws IOException { out.write(expression.value.toString()); } private void outputFunctionExpression(ExpressionNode expression) throws IOException, OutputError { Iterator<Node> params = expression.children.iterator(); // First parameter is obligatory as it's the function name if (params.hasNext()) { Node name = params.next(); if(name.type != Expression.Type.VALUE) throw new OutputError("function name must be a simple value."); outputValueExpression((ValueNode<?>)name); out.write("("); // Subsequent parameters are optional; we have to piss about to put the commas in the right places if (params.hasNext()) { outputExpression(params.next()); while(params.hasNext()) { out.write(","); outputExpression(params.next()); } } out.write(")"); } else { throw new OutputError("First parameter of a function expression must be function name"); } } private static int getPriority(Expression.Type operator) { switch(operator) { case VALUE: case PARAM: return 100; case NOT: return 95; case DIV: return 90; case MUL: return 80; case ADD: return 70; case SUB: return 60; case LT: case GT: case LTE: case GTE: case EQ: return 40; case AND: return 20; case OR: return 10; default: return 0; } } private static boolean isAssociative(Expression.Type operator) { switch(operator) { case ADD: case MUL: return true; default: return false; } } public <T> void writeValue(T value) { top.children.add(new ValueNode<T>(Expression.Type.VALUE, value)); } public void writeParameter(String name) { top.children.add(new ValueNode<String>(Expression.Type.PARAM, name)); } public void beginExpression(Expression.Type type) { if (top != null) stack.push(top); top = new ExpressionNode(type); } public void endExpression(Expression.Type type) throws OutputError { if (top.type != type) throw new OutputError("Mismatched type in beginExpression and endExpression"); if (stack.empty()) { try { outputExpression(top); out.flush(); top = null; } catch (java.io.IOException e) { throw new OutputError(e.getMessage()); } } else { ExpressionNode parent = stack.pop(); parent.children.add(top); top = parent; } } /** Initialise a SimpleExpressionWriter. * * @param out Where to write the resulting expression * @param operators A map of strings to output for values of Expression.Type */ public SimpleExpressionWriter( Writer out, Map<Expression.Type, String> string_map, Set<Expression.Type> infix_operators, Set<Expression.Type> prefix_operators) { this.out = out; this.operators = string_map; this.infix_operators = infix_operators; this.prefix_operators = prefix_operators; } /** Initialise a SimpleExpressionWriter. * * Equivalent to SimpleExpressionWriter(out, DEFAULT_STRING_MAP, DEFAULT_INFIX_SET, DEFAULT_PREFIX_SET); * * @param out Where to write the resulting expression */ public SimpleExpressionWriter(Writer out) { this.out = out; this.operators = DEFAULT_STRING_MAP; this.infix_operators = DEFAULT_INFIX_SET; this.prefix_operators = DEFAULT_PREFIX_SET; } } --- NEW FILE: ValueExpression.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.expression; /** A simple expression containing a single value. * * @author jonathan */ public class ValueExpression<T> implements Expression { private T value; public void write(ExpressionWriter writer) throws OutputError { writer.writeValue(value); } public ValueExpression(T value) { this.value = value; } } |
|
From: <je...@23...> - 2008-10-06 10:23:16
|
Update of /cvsroot/era/src/org/jdaemon/era/helper In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/era/helper Modified Files: AbstractCube.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' Index: AbstractCube.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/helper/AbstractCube.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** AbstractCube.java 13 Feb 2008 21:40:15 -0000 1.2 --- AbstractCube.java 6 Oct 2008 10:22:14 -0000 1.3 *************** *** 17,20 **** --- 17,21 ---- import org.jdaemon.util.comparator.ReverseComparator; import org.jdaemon.util.QuickList; + import org.jdaemon.util.attribute.Attribute; import java.util.Comparator; *************** *** 35,182 **** * @author Jonathan Essex */ ! public abstract class AbstractCube extends java.util.AbstractCollection implements Cube { ! ! ! /** Helper for calculation of aggregate values on a Cube. ! */ ! private abstract class Accumulator<T> { ! ! /** Current value of calculated aggregate ! */ ! private T value; ! ! /** Attribute of cube on which aggregate calculation is to be performed ! */ ! private String attribute; ! ! /** Function used to calculate aggregate value. ! * <P> ! * To calculate aggregate value A, for each of 1..i values of attribute a in cube, perform: ! * </P><P> ! * A<sub>i</sub> = operate(a<sub>i</sub>, A<sub>i-1</sub>) ! * </P><P> ! * The final value of A<sub>i</sub> is the aggregate value; The initial value A<sub>0</sub> ! * is set in the constructor. ! * </P> ! * @param value a<sub>i</sub> ! * @param accumulator A<sub>i-1</sub> ! * @return A<sub>i</sub> ! */ ! protected abstract T operate(Object value, T accumulator); ! ! /** Get the calculated aggregate value. ! * ! * @return The value of the calculated aggregate. ! */ ! public T getValue() { ! return value; ! } ! ! /** Get an attribute value from a point reference within this cube. ! * ! * @param point_ref A point reference (returned by Cube.iterator()) ! * @return The value of the attribute specified in the constructor at the given point ! */ ! private Object getAttr(Object point_ref) { ! return getAttribute(attribute, point_ref); ! } ! ! /** Perform one step of calculation. ! * ! * Given an Accumulator accum and a cube iterator i, the value of an aggregate can be calculated with: ! * <code> ! * while i.hasNext() accum.accumulate(i.next()); ! * </code> ! * ! * @param point_ref a point reference within a cube. ! */ ! public void accumulate(Object point_ref) { ! value = operate(getAttr(point_ref), value); ! } ! ! /** Create a new Accumulator ! * ! * @param value initial value for aggregate (A<sub>0</sub>) ! * @param attribute Attribute on which aggregation is to be calculated ! */ ! protected Accumulator(T value, String attribute) { ! this.value = value; ! this.attribute = attribute; ! } ! } ! ! /** Accumulator for determining max value of an attribute. ! * ! * Note assumption that the attribute value can be cast to T, and ! * also that getComparator(attribute) can be cast to Comparator<T> ! * ! * @param T type of maximum value to calculate ! */ ! private class MaxAccumulator<T> extends Accumulator<T> { ! protected Comparator<T> comparator; ! ! protected T operate(Object value, T accumulator) { ! if (accumulator == null) ! return (T)value; ! else ! return comparator.compare((T)value, accumulator) > 0 ? (T)value : accumulator; ! } ! ! public MaxAccumulator(String attribute) { ! super(null, attribute); ! comparator = (Comparator<T>)getComparator(attribute); ! } ! } ! ! /** Accumulator for determining min value of an attribute. ! * ! * Note assumption that the attribute value can be cast to T, and ! * also that getComparator(attribute) can be cast to Comparator<T> ! * ! * @param T type of maximum value to calculate ! */ ! private class MinAccumulator<T> extends Accumulator<T> { ! protected Comparator<T> comparator; ! ! protected T operate(Object value, T accumulator) { ! if (accumulator == null) ! return (T)value; ! else ! return comparator.compare((T)value, accumulator) < 0 ? (T)value : accumulator; ! } ! ! public MinAccumulator(String attribute) { ! super(null, attribute); ! comparator = (Comparator<T>)getComparator(attribute); ! } ! } ! ! /** Accumulator for determining sum of an attribute. ! * ! * Note assumption that the attribute value can be cast to Number ! * ! */ ! private class SumAccumulator extends Accumulator<Double> { ! ! protected Double operate(Object value, Double accumulator) { ! return new Double(((Number)value).doubleValue() + accumulator.doubleValue()); ! } ! ! public SumAccumulator(String attribute) { ! super(new Double(0.0), attribute); ! } ! } ! ! private class CountAccumulator extends Accumulator<Long> { ! ! protected Long operate(Object value, Long accumulator) { ! return value == null ? accumulator : new Long(accumulator.longValue() + 1); ! } ! public CountAccumulator(String attribute) { ! super(new Long(0), attribute); ! } ! } ! /** Add all the data items in the given Cube * --- 36,42 ---- * @author Jonathan Essex */ ! public abstract class AbstractCube<C> extends java.util.AbstractCollection<C> implements Cube<C> { ! /** Add all the data items in the given Cube * *************** *** 187,217 **** * @author Jonathan Essex */ ! public void addAll(Cube cube) { ! } ! ! /** Get a comparator object which orders an attribute of this cube ! * ! * The default implementation returns a default comparator which assumes the attribute ! * is of a type that implements Comparable. ! * ! * @param attribute The name of an attribute ! * @returns A comparator which orders the named attribute ! */ ! public Comparator<?> getComparator(String attribute) { ! return getDescriptor().getComparator(attribute); ! } ! ! /** Return a set of all the values of a given attribute across all contained objects ! * ! * @param attribute Attribute name for which set of values is to be retrieved ! * @returns A set of all the values of the given attribute within this cube ! * @author Jonathan Essex ! */ ! public SortedSet getAttributeSet(String attribute) { ! Iterator i = iterator(); ! SortedSet attribs = new TreeSet(getComparator(attribute)); ! while (i.hasNext()) attribs.add(getAttribute(attribute, i.next())); ! return attribs; } /** Create a new cube containing some subset of the contents of this cube --- 47,53 ---- * @author Jonathan Essex */ ! public void addAll(Cube<C> cube) { } + /** Create a new cube containing some subset of the contents of this cube *************** *** 227,231 **** * @returns A cube containing a subset of the objects in this cube */ ! public Cube constrain(String attribute, int constraint_type, Object value) { FilterFactory filter_factory = new FilterFactory(getDescriptor()); --- 63,67 ---- * @returns A cube containing a subset of the objects in this cube */ ! public <T extends Comparable<? super T>> Cube<C> constrain(Attribute<T,C> attribute, int constraint_type, T value) { FilterFactory filter_factory = new FilterFactory(getDescriptor()); |
Update of /cvsroot/era/src/org/jdaemon/era In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/era Modified Files: Aggregate.java Constraint.java ConstraintFactory.java Cube.java CubeDescriptor.java Grouping.java Report.java Sort.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' Index: Aggregate.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Aggregate.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Aggregate.java 12 Feb 2008 23:05:03 -0000 1.9 --- Aggregate.java 6 Oct 2008 10:22:14 -0000 1.10 *************** *** 11,14 **** --- 11,16 ---- package org.jdaemon.era; + import org.jdaemon.util.attribute.Attribute; + /** Specifies an aggregate value to be calculated by a Cube. * <P> *************** *** 30,34 **** * @author Jonathan Essex */ ! public class Aggregate { /** Parameter value indicating sum of attribute values should be calculated */ --- 32,36 ---- * @author Jonathan Essex */ ! public class Aggregate<T extends Comparable<? super T>,C> { /** Parameter value indicating sum of attribute values should be calculated */ *************** *** 44,48 **** private int type; /** Cube attribute on which to perform aggregation operation */ ! private String attribute; /** Creates a new instance of Aggregate. --- 46,50 ---- private int type; /** Cube attribute on which to perform aggregation operation */ ! private Attribute<T,C> attribute; /** Creates a new instance of Aggregate. *************** *** 51,57 **** * @param type Type of aggregation (one of SUM, MIN, MAX, COUNT) */ ! public Aggregate(String attribute_name, int type) { this.type = type; ! this.attribute = attribute_name; } --- 53,59 ---- * @param type Type of aggregation (one of SUM, MIN, MAX, COUNT) */ ! public Aggregate(Attribute<T,C> attribute, int type) { this.type = type; ! this.attribute = attribute; } *************** *** 65,105 **** return type; } ! ! /** Get the attriubte name on which aggregation will be performed. ! * ! * Will return the exact attribute name specified in the constructor. ! * ! * @return the attriubte name on which aggregation will be performed ! */ ! public String getAttributeName() { ! return attribute; ! } ! ! /** Get the value of this aggregate from a cube. ! * ! * If <code>attribute_name</code> is the values specified in constructor, ! * then this operation is equivalent to one of the following: ! * <LU> ! * <LI><CODE>new Double(cube.getSum(attribute_name))</CODE></LI> ! * <LI><CODE>cube.getMax(attribute_name)</CODE></LI> ! * <LI><CODE>cube.getMin(attribute_name)</CODE></LI> ! * <LI><CODE>cube.getCount(attribute_name)</CODE></LI> ! * </LU> ! * depending on the value of <code>type</code> which was specified in the constructor. ! * ! * @param cube Cube from which to extract aggregate value ! * @return the specified attribute value ! */ ! public Object getValue(Cube cube) { ! switch(type) { ! case SUM: return new Double(cube.getSum(attribute)); ! case MAX: return cube.getMax(attribute); ! case MIN: return cube.getMin(attribute); ! //Hmm... this isn't right. Need an actual getCount(attr_name) method in Cube... ! case COUNT: return new Integer(cube.size()); ! default: throw new RuntimeException("Unknown aggregate type."); ! } ! } ! /** Equality test. * --- 67,71 ---- return type; } ! /** Equality test. * Index: Constraint.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Constraint.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Constraint.java 11 Jun 2004 23:24:23 -0000 1.4 --- Constraint.java 6 Oct 2008 10:22:14 -0000 1.5 *************** *** 21,25 **** * @author Jonathan Essex */ ! public interface Constraint { /** Apply a constraint to a cube. --- 21,25 ---- * @author Jonathan Essex */ ! public interface Constraint<T> { /** Apply a constraint to a cube. *************** *** 28,31 **** * @return Cube containing subset of data for which constraint is satisifed. */ ! Cube apply(Cube cube); } --- 28,31 ---- * @return Cube containing subset of data for which constraint is satisifed. */ ! Cube<T> apply(Cube<T> cube); } Index: ConstraintFactory.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/ConstraintFactory.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ConstraintFactory.java 12 Feb 2008 23:05:04 -0000 1.5 --- ConstraintFactory.java 6 Oct 2008 10:22:14 -0000 1.6 *************** *** 10,13 **** --- 10,15 ---- package org.jdaemon.era; + import org.jdaemon.util.attribute.Attribute; + /** Factory interface for building constraints. * *************** *** 23,27 **** * @author Jonathan Essex */ ! public interface ConstraintFactory { --- 25,29 ---- * @author Jonathan Essex */ ! public interface ConstraintFactory<C> { *************** *** 36,40 **** * @return A constraint encapsulating the constraint <I>attribute</I> less than <I>operand</I> */ ! public Constraint newLess(String attribute, Object operand); /** Create a new 'greater' constraint. --- 38,42 ---- * @return A constraint encapsulating the constraint <I>attribute</I> less than <I>operand</I> */ ! public <T extends Comparable<? super T>> Constraint<C> newLess(Attribute<T,C> attribute, T operand); /** Create a new 'greater' constraint. *************** *** 48,52 **** * @return A constraint encapsulating the constraint <I>attribute</I> greater than <I>operand</I> */ ! public Constraint newGreater(String attribute, Object operand); /** Create a new 'greater or equal' constraint. --- 50,54 ---- * @return A constraint encapsulating the constraint <I>attribute</I> greater than <I>operand</I> */ ! public <T extends Comparable<? super T>> Constraint<C> newGreater(Attribute<T,C> attribute, T operand); /** Create a new 'greater or equal' constraint. *************** *** 60,64 **** * @return A constraint encapsulating the constraint <I>attribute</I> greater than or equal to<I>operand</I> */ ! public Constraint newGreaterOrEqual(String attribute, Object operand); /** Create a new 'less or equal' constraint. --- 62,66 ---- * @return A constraint encapsulating the constraint <I>attribute</I> greater than or equal to<I>operand</I> */ ! public <T extends Comparable<? super T>> Constraint<C> newGreaterOrEqual(Attribute<T,C> attribute, T operand); /** Create a new 'less or equal' constraint. *************** *** 72,76 **** * @return A constraint encapsulating the constraint <I>attribute</I> less than or equal to<I>operand</I> */ ! public Constraint newLessOrEqual(String attribute, Object operand); /** Create a new 'equal' constraint. --- 74,78 ---- * @return A constraint encapsulating the constraint <I>attribute</I> less than or equal to<I>operand</I> */ ! public <T extends Comparable<? super T>> Constraint<C> newLessOrEqual(Attribute<T,C> attribute, T operand); /** Create a new 'equal' constraint. *************** *** 84,88 **** * @return A constraint encapsulating the constraint <I>attribute</I> equal to <I>operand</I> */ ! public Constraint newEqual(String attribute, Object operand); /** Create a new 'and' constraint. --- 86,90 ---- * @return A constraint encapsulating the constraint <I>attribute</I> equal to <I>operand</I> */ ! public <T extends Comparable<? super T>> Constraint<C> newEqual(Attribute<T,C> attribute, T operand); /** Create a new 'and' constraint. *************** *** 95,99 **** * @return A constraint encapsulating constraint <I>a</I> and <I>b</I> */ ! public Constraint newAnd(Constraint a, Constraint b); ! } --- 97,100 ---- * @return A constraint encapsulating constraint <I>a</I> and <I>b</I> */ ! public Constraint<C> newAnd(Constraint<C> a, Constraint<C> b); } Index: Cube.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Cube.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Cube.java 11 Jun 2004 23:24:23 -0000 1.10 --- Cube.java 6 Oct 2008 10:22:14 -0000 1.11 *************** *** 14,17 **** --- 14,19 ---- import java.util.SortedSet; import java.util.Collection; + import java.util.List; + import org.jdaemon.util.attribute.Attribute; /** Supports generic slicing-and-dicing of data using an OLAP cube metaphor. *************** *** 57,61 **** * @author Jonathan Essex */ ! public interface Cube extends Collection { /** operator that selects objects with attribute equal to a value */ --- 59,63 ---- * @author Jonathan Essex */ ! public interface Cube<T> extends Collection<T> { /** operator that selects objects with attribute equal to a value */ *************** *** 89,99 **** * @return A cube containing a subset of the objects in this cube */ ! public Cube constrain(String attribute, int operator, Object operand); /** Calculate several aggregate values for this cube at the same time. ! * @param aggregates array of aggregate objects specifying what calculations to perform ! * @return an array of result objects */ ! public Object[] getAggregates(Aggregate[] aggregates); /** Gets the sum over all contained objects of some attributes. --- 91,115 ---- * @return A cube containing a subset of the objects in this cube */ ! public <V extends Comparable<? super V>> Cube<T> constrain(Attribute<V,T> attr, int operator, T operand); /** Calculate several aggregate values for this cube at the same time. ! * ! * The nth item in the result list should be equal to the result of ! * calling getAggregate on teh nth item in the aggregates list. ! * ! * @param aggregates List of aggregate objects specifying what calculations to perform ! * @return a List of result objects */ ! public List<?> getAggregates(List<Aggregate<?,T>> aggregates); ! ! ! /** Get an aggregate value ! * ! * Should be equivalent to calling aggregate.getAttribute() ! * ! * @param an aggregate to calculate ! * @return The value of an aggregate calculated over all points in the cube ! */ ! public <V extends Comparable<? super V>> V getAggregate(Aggregate<V,T> aggregate); /** Gets the sum over all contained objects of some attributes. *************** *** 107,113 **** * * @param attribute The name of an attribute to sum ! * @return The sum of the named attribute over all contained objects */ ! public double getSum(String attribute); /** Get the minimum value over all contained objects of some attribute. --- 123,129 ---- * * @param attribute The name of an attribute to sum ! * @return The sum of the given attribute over all contained objects */ ! public <V extends Comparable<? super V>> V getSum(Attribute<V,T> attribute); /** Get the minimum value over all contained objects of some attribute. *************** *** 116,123 **** * comparison operation used to create this minimum. * ! * @param attribute The name of an attribute * @return The minimum value of the named attribute over all contained objects */ ! public Object getMin(String attribute); /** Get the maximum value over all contained objects of some attribute. --- 132,139 ---- * comparison operation used to create this minimum. * ! * @param attribute The an attribute * @return The minimum value of the named attribute over all contained objects */ ! public <V extends Comparable<? super V>> V getMin(Attribute<V,T> attribute); /** Get the maximum value over all contained objects of some attribute. *************** *** 129,133 **** * @return The maximum value of the named attribute over all contained objects */ ! public Object getMax(String attribute); /** Get the first non-null value over all contained objects of some attribute. --- 145,149 ---- * @return The maximum value of the named attribute over all contained objects */ ! public <V extends Comparable<? super V>> V getMax(Attribute<V,T> attribute); /** Get the first non-null value over all contained objects of some attribute. *************** *** 139,143 **** * @return The maximum value of the named attribute over all contained objects */ ! public Object getFirst(String attribute); /** Get the last non-null value over all contained objects of some attribute. --- 155,159 ---- * @return The maximum value of the named attribute over all contained objects */ ! public <V extends Comparable<? super V>> V getFirst(Attribute<V,T> attribute); /** Get the last non-null value over all contained objects of some attribute. *************** *** 149,153 **** * @return The maximum value of the named attribute over all contained objects */ ! public Object getLast(String attribute); /** Get the value of an individual attribute of an object contained by this cube. --- 165,169 ---- * @return The maximum value of the named attribute over all contained objects */ ! public <V extends Comparable<? super V>> V getLast(Attribute<V,T> attribute); /** Get the value of an individual attribute of an object contained by this cube. *************** *** 157,161 **** * @return The value of the named attribute at the provided point reference */ ! public Object getAttribute(String attribute, Object point_ref); /** Get an iterator over all points (objects) within this cube. --- 173,177 ---- * @return The value of the named attribute at the provided point reference */ ! public <V extends Comparable<? super V>> V getAttribute(Attribute<V,T> attribute, T obj); /** Get an iterator over all points (objects) within this cube. *************** *** 169,180 **** * @return An iterator of <I>point references</I> */ ! public Iterator iterator(); - /** Get a set of all the values of a given attribute across all contained objects. - * - * @param attribute Attribute name for which set of values is to be retrieved - * @return A set of all the values of the given attribute within this cube - */ - public SortedSet getAttributeSet(String attribute); /** Group data by a given attribute. --- 185,190 ---- * @return An iterator of <I>point references</I> */ ! public Iterator<T> iterator(); /** Group data by a given attribute. *************** *** 188,192 **** * @return An iterator over Cubes containing elements with the same attribute value */ ! public Iterator groupBy(Sort sort); /** Group data by several attributes. --- 198,202 ---- * @return An iterator over Cubes containing elements with the same attribute value */ ! public Iterator<Cube<T>> groupBy(Sort sort); /** Group data by several attributes. *************** *** 199,203 **** * @return An iterator over Cubes containing elements with the same attribute value */ ! public Iterator groupBy(Sort[] sorts); /** Add all the data items in the given Cube to this cube. --- 209,213 ---- * @return An iterator over Cubes containing elements with the same attribute value */ ! public Iterator<Cube<T>> groupBy(Sort[] sorts); /** Add all the data items in the given Cube to this cube. *************** *** 208,212 **** * @param cube Collection of elements to add */ ! public void addAll(Cube cube); /** Get metadata describing this cube. --- 218,222 ---- * @param cube Collection of elements to add */ ! public void addAll(Cube<T> cube); /** Get metadata describing this cube. *************** *** 214,218 **** * @return A CubeDescriptor object describing the properties of this Cube */ ! public CubeDescriptor getDescriptor(); /** Create a cube containing the union of data in this cube and some other cube. --- 224,228 ---- * @return A CubeDescriptor object describing the properties of this Cube */ ! public CubeDescriptor<T> getDescriptor(); /** Create a cube containing the union of data in this cube and some other cube. *************** *** 221,224 **** * @return a cube containing the union of data in this cube and <I>other</I> */ ! public Cube union(Cube other); } --- 231,234 ---- * @return a cube containing the union of data in this cube and <I>other</I> */ ! public Cube<T> union(Cube<T> other); } Index: CubeDescriptor.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/CubeDescriptor.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CubeDescriptor.java 11 Jun 2004 23:24:23 -0000 1.5 --- CubeDescriptor.java 6 Oct 2008 10:22:14 -0000 1.6 *************** *** 11,19 **** package org.jdaemon.era; ! import org.jdaemon.util.AttributeList; ! import org.jdaemon.util.Accessor; import java.util.Iterator; - import java.util.Comparator; /** Represents metadata describing a cube. --- 11,18 ---- package org.jdaemon.era; ! import org.jdaemon.util.attribute.Attribute; + import java.util.Map; import java.util.Iterator; /** Represents metadata describing a cube. *************** *** 26,30 **** * @author Jonathan Essex */ ! public interface CubeDescriptor { /** Make a new cube of the type described by this Descriptor --- 25,29 ---- * @author Jonathan Essex */ ! public interface CubeDescriptor<T> { /** Make a new cube of the type described by this Descriptor *************** *** 32,36 **** * @return A root cube describing a particular universe of data. */ ! Cube makeCube(); /** Get the names of all attributes of the described cubes. --- 31,35 ---- * @return A root cube describing a particular universe of data. */ ! public Cube<T> makeCube(); /** Get the names of all attributes of the described cubes. *************** *** 40,77 **** * @return An iterator over all the attributes. */ ! Iterator getAttributeNames(); ! /** Get metadata attributes for a given cube attribute. ! * ! * Note: This should probably return a DataRepresentation... (JE) ! * @return An AttributeList containing all the metadata associated with a given attribute. ! * @param attribute_name Name of the attribute for which metadata is to be retrieved ! */ ! AttributeList getMetadata(String attribute_name); ! /** Get accessor for cube attributes. ! * ! * It is perfectly valid for this method to return null; this would be the case where ! * a cube has no accessor or the accessor is dependent on a cube instance rather than ! * common to all cubes sharing a given descriptor. ! * ! * @return An Accessor object capable of retrieving attribute values from any point reference obtained from a cube of this type. ! */ ! Accessor getAccessor(); - /** Get comparator for a given attribute. - * <P> - * It is prefectly valid for this method to return null; this would be the case where - * a cube performs its own comparision operations (for instance using some underling SQL - * database) and a java Comparator object is not therefore useful. - * </P><P> - * Implementors are encouraged however to implement this method to return something which - * has as similar as possible (ideally identical) semantics to the comparison operations - * performed by the underlying data store. This will be necessary for some advanced features - * (such as in-process data caching) to perform correctly. - * </P> - * @return A comparator object valid for values of the given attribute. - * @param attribute_name Name of the attribute for which Comparator is to be found. - */ - Comparator getComparator(String attribute_name); } --- 39,50 ---- * @return An iterator over all the attributes. */ ! public Iterator<String> getAttributeNames(); ! ! public Attribute<?,T> getAttribute(String name); ! public Map<String,Attribute<?,T>> getAttributeMap(); ! public Iterator<Attribute<?,T>> getAttributes(); } + Index: Grouping.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Grouping.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Grouping.java 13 Jun 2004 21:05:18 -0000 1.11 --- Grouping.java 6 Oct 2008 10:22:14 -0000 1.12 *************** *** 11,17 **** package org.jdaemon.era; import java.util.List; - import java.util.ArrayList; - import java.util.Arrays; /** Describes and manipulates a single 'grouping level' within a Report. --- 11,17 ---- package org.jdaemon.era; + import org.jdaemon.util.attribute.Attribute; + import java.util.List; /** Describes and manipulates a single 'grouping level' within a Report. *************** *** 19,23 **** * @author Jonathan Essex */ ! public interface Grouping { /** Add a sort to the current grouping level. --- 19,23 ---- * @author Jonathan Essex */ ! public interface Grouping<C> { /** Add a sort to the current grouping level. *************** *** 27,31 **** * @param sort sort to add */ ! public void addSort(Sort sort); /** Add an aggregate to the current grouping level. --- 27,31 ---- * @param sort sort to add */ ! public <T extends Comparable<? super T>> void addSort(Sort<T,C> sort); /** Add an aggregate to the current grouping level. *************** *** 35,39 **** * @param aggregate aggregate to add */ ! public void addAggregate(Aggregate aggregate); /** Sets the sorts for the current grouping level. --- 35,39 ---- * @param aggregate aggregate to add */ ! public <T extends Comparable<? super T>> void addAggregate(Aggregate<T,C> aggregate); /** Sets the sorts for the current grouping level. *************** *** 41,47 **** * Optional - read-only grouping need not implement this method. * ! * @param sorts Array of sorts which defines how data within the current grouping level will be sorted */ ! public void setSorts(Sort[] sorts); /** Sets the aggregates for the current grouping level. --- 41,47 ---- * Optional - read-only grouping need not implement this method. * ! * @param sorts List of sorts which defines how data within the current grouping level will be sorted */ ! public void setSorts(List<Sort<?,C>> sorts); /** Sets the aggregates for the current grouping level. *************** *** 51,65 **** * @param aggregate aggregate to add */ ! public void setAggregates(Aggregate[] aggregates); /** Add an aggregate function to the current grouping level. * * Optional - read-only grouping need not implement this method. ! * Equivalent to addAggregate(new Aggregate(attribute_name, type)). * * @param attribute_name Name of attribute on which aggregation will be performed * @param type Type of aggregation to perform (one of Aggregate.SUM, Aggregate.MAX... etc) */ ! public void addAggregate(String attribute_name, int type); /** Add a sort to the current grouping level --- 51,65 ---- * @param aggregate aggregate to add */ ! public void setAggregates(List<Aggregate<?,C>> aggregates); /** Add an aggregate function to the current grouping level. * * Optional - read-only grouping need not implement this method. ! * Equivalent to addAggregate(new Aggregate(attribute, type)). * * @param attribute_name Name of attribute on which aggregation will be performed * @param type Type of aggregation to perform (one of Aggregate.SUM, Aggregate.MAX... etc) */ ! public <T extends Comparable<? super T>> void addAggregate(Attribute<T,C> attr, int type); /** Add a sort to the current grouping level *************** *** 68,75 **** * Equivalent to addSort(new Sort(attribute_name, direction)). * ! * @param attribute_name Name of attribute to sort * @param direction direction of sort (one of Sort.ASCENDING, Sort.DESCENDING) */ ! public void addSort(String attribute_name, int direction); /** Get a list of the Sorts in the current grouping level. --- 68,75 ---- * Equivalent to addSort(new Sort(attribute_name, direction)). * ! * @param attribute attribute to sort * @param direction direction of sort (one of Sort.ASCENDING, Sort.DESCENDING) */ ! public <T extends Comparable<? super T>> void addSort(Attribute<T,C> attribute, int direction); /** Get a list of the Sorts in the current grouping level. *************** *** 77,81 **** * @return A List of Sort objects. */ ! public List getSorts(); /** Get a list of all the Aggregates in the current grouping level. --- 77,81 ---- * @return A List of Sort objects. */ ! public List<Sort<?,C>> getSorts(); /** Get a list of all the Aggregates in the current grouping level. *************** *** 83,100 **** * @return a List of Aggregate objects */ ! public List getAggregates(); /** Get a list of the Sorts in the current grouping level. ! * ! * @return A List of Sort objects. ! */ ! public Sort[] getSortsArray(); ! ! /** Get a list of all the Aggregates in the current grouping level. ! * ! * @return a List of Aggregate objects ! */ ! public Aggregate[] getAggregatesArray(); ! /** Get the Formatting object for the current grouping level. * --- 83,90 ---- * @return a List of Aggregate objects */ ! public List<Aggregate<?,C>> getAggregates(); /** Get a list of the Sorts in the current grouping level. ! /** Get the Formatting object for the current grouping level. * *************** *** 113,117 **** * @return true if this grouping can be changed. */ ! public boolean isModifiable(); ! } --- 103,106 ---- * @return true if this grouping can be changed. */ ! public boolean isModifiable(); } Index: Report.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Report.java,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** Report.java 14 Jun 2004 17:50:35 -0000 1.13 --- Report.java 6 Oct 2008 10:22:14 -0000 1.14 *************** *** 22,26 **** * @author Jonathan Essex */ ! public interface Report { /** Get an XML view of a cube. --- 22,26 ---- * @author Jonathan Essex */ ! public interface Report<C> { /** Get an XML view of a cube. *************** *** 36,40 **** * @return An XMLWritable view of the given cube */ ! public XMLWritable getXMLView(Cube cube) throws CubeException; /** Build an XML view describing this Report using information from the cube descriptor. --- 36,40 ---- * @return An XMLWritable view of the given cube */ ! public XMLWritable getXMLView(Cube<C> cube) throws CubeException; /** Build an XML view describing this Report using information from the cube descriptor. *************** *** 47,51 **** * @return An XMLWritable view describing the document generated by this report operating on a cube of the given type */ ! public XMLWritable getXMLViewDescriptor(CubeDescriptor descriptor) throws CubeException; /** Get the grouping associated with a report. --- 47,51 ---- * @return An XMLWritable view describing the document generated by this report operating on a cube of the given type */ ! public XMLWritable getXMLViewDescriptor(CubeDescriptor<C> descriptor) throws CubeException; /** Get the grouping associated with a report. *************** *** 59,63 **** * @return a List of Grouping objects */ ! public List groupingsList(); /** Create a new Grouping which can be added to the groupings list. --- 59,63 ---- * @return a List of Grouping objects */ ! public List<Grouping<C>> groupingsList(); /** Create a new Grouping which can be added to the groupings list. *************** *** 65,69 **** * @return A new Grouping which can be added to the groupings list. */ ! public Grouping newGrouping(); /** Set whether report shows detail data within bottom-most grouping level. --- 65,69 ---- * @return A new Grouping which can be added to the groupings list. */ ! public Grouping<C> newGrouping(); /** Set whether report shows detail data within bottom-most grouping level. Index: Sort.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Sort.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Sort.java 12 Feb 2008 23:05:03 -0000 1.9 --- Sort.java 6 Oct 2008 10:22:14 -0000 1.10 *************** *** 10,13 **** --- 10,14 ---- package org.jdaemon.era; + import org.jdaemon.util.attribute.Attribute; /** Specifies a sort operation which a Cube can apply to data. *************** *** 15,19 **** * @author Jonathan Essex */ ! public class Sort { /** Parameter value indicating an ascending sort order --- 16,20 ---- * @author Jonathan Essex */ ! public class Sort<T extends Comparable<? super T>,C> { /** Parameter value indicating an ascending sort order *************** *** 24,28 **** public static final int DESCENDING = 1; ! private String attribute_name; private int direction; --- 25,29 ---- public static final int DESCENDING = 1; ! private Attribute<T,C> attribute; private int direction; *************** *** 31,36 **** * @param direction Direction of sort (either SORT_ASCENDING or SORT_DESCENDING) */ ! public Sort(String attribute_name, int direction) { ! this.attribute_name = attribute_name; this.direction = direction; } --- 32,37 ---- * @param direction Direction of sort (either SORT_ASCENDING or SORT_DESCENDING) */ ! public Sort(Attribute<T,C> attribute, int direction) { ! this.attribute = attribute; this.direction = direction; } *************** *** 44,53 **** } ! /** Get attribute name. * ! * @return value of attribute name property */ ! public String getAttributeName() { ! return attribute_name; } --- 45,54 ---- } ! /** Get attribute * ! * @return Attribute property */ ! public Attribute<T,C> getAttribute() { ! return attribute; } *************** *** 55,59 **** public int hashCode() { int hash = 7; ! hash = 53 * hash + (this.attribute_name != null ? this.attribute_name.hashCode() : 0); hash = 53 * hash + this.direction; return hash; --- 56,60 ---- public int hashCode() { int hash = 7; ! hash = 53 * hash + (this.attribute != null ? this.attribute.hashCode() : 0); hash = 53 * hash + this.direction; return hash; *************** *** 69,73 **** if (obj instanceof Sort) { Sort other = (Sort)obj; ! return (this.direction == other.direction && this.attribute_name.equals(other.attribute_name)); } else { return false; --- 70,74 ---- if (obj instanceof Sort) { Sort other = (Sort)obj; ! return (this.direction == other.direction && this.attribute.equals(other.attribute)); } else { return false; |
|
From: <je...@23...> - 2008-10-06 10:23:16
|
Update of /cvsroot/era/src/org/jdaemon/era/filter In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12559/era/filter Modified Files: FilterFactory.java Log Message: Various changes for ERA v2 - 'This time it's Generic...' Index: FilterFactory.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/filter/FilterFactory.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FilterFactory.java 1 Jun 2004 15:46:45 -0000 1.3 --- FilterFactory.java 6 Oct 2008 10:22:14 -0000 1.4 *************** *** 23,27 **** * @author Jonathan Essex */ ! public class FilterFactory implements ConstraintFactory { private static class Less extends AttributeFilter { --- 23,27 ---- * @author Jonathan Essex */ ! public class FilterFactory<C> implements ConstraintFactory<C> { private static class Less extends AttributeFilter { |
Update of /cvsroot/era/src/org/jdaemon/util/functional In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12195/functional Modified Files: BinaryFunction.java CountFunction.java MaxFunction.java MinFunction.java Operations.java UnaryFunction.java Added Files: AbstractBinaryFunction.java AbstractBinaryOperator.java AbstractUnaryFunction.java AbstractUnaryOperator.java Arithmetic.java ArithmeticOperations.java Parameter.java Log Message: Modifications for ERA v2 - this time it's Generic... --- NEW FILE: AbstractBinaryFunction.java --- package org.jdaemon.util.functional; import org.jdaemon.util.expression.*; public abstract class AbstractBinaryFunction<A, B, R> implements BinaryFunction<A,B,R> { public abstract R operate(A a, B b); public void write(ExpressionWriter out) throws OutputError { out.beginExpression(Expression.Type.FUNC); out.writeValue(getClass()); out.writeParameter("a"); out.writeParameter("b"); out.endExpression(Expression.Type.FUNC); } } --- NEW FILE: AbstractBinaryOperator.java --- package org.jdaemon.util.functional; import org.jdaemon.util.expression.Expression; import org.jdaemon.util.expression.ExpressionWriter; import org.jdaemon.util.expression.OutputError; abstract class AbstractBinaryOperator<A, B, R> implements BinaryFunction<A, B, R> { private Expression.Type type; public abstract R operate(A a, B b); public void write(ExpressionWriter out) throws OutputError { out.beginExpression(type); out.writeParameter("a"); out.writeParameter("b"); out.endExpression(type); } public AbstractBinaryOperator(Expression.Type type) { super(); this.type = type; } } --- NEW FILE: AbstractUnaryFunction.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; import org.jdaemon.util.expression.*; /** * * @author jonathan */ public abstract class AbstractUnaryFunction<A,R> implements UnaryFunction<A,R> { public abstract R operate(A value); public void write(ExpressionWriter writer) throws OutputError { writer.beginExpression(Expression.Type.FUNC); writer.writeValue(getClass()); writer.writeParameter("value"); writer.endExpression(Expression.Type.FUNC); } } --- NEW FILE: AbstractUnaryOperator.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; import org.jdaemon.util.expression.Expression; import org.jdaemon.util.expression.ExpressionWriter; import org.jdaemon.util.expression.OutputError; abstract class AbstractUnaryOperator<A, R> implements UnaryFunction<A, R> { private Expression.Type type; public abstract R operate(A a); public void write(ExpressionWriter out) throws OutputError { out.beginExpression(type); out.writeParameter("a"); out.endExpression(type); } public AbstractUnaryOperator(Expression.Type type) { super(); this.type = type; } } --- NEW FILE: Arithmetic.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; /** * * @author jonathan */ public interface Arithmetic<T> { T add(T a, T b); T mul(T a, T b); T div(T a, T b); T sub(T a, T b); T zero(); T one(); public static final Arithmetic<Integer> INTEGER = new Arithmetic<Integer>() { public final Integer add(Integer a, Integer b) { return new Integer(a.intValue() + b.intValue()); } public final Integer sub(Integer a, Integer b) { return new Integer(a.intValue() - b.intValue()); } public final Integer mul(Integer a, Integer b) { return new Integer(a.intValue() * b.intValue()); } public final Integer div(Integer a, Integer b) { return new Integer(a.intValue() / b.intValue()); } public final Integer zero() { return new Integer(0); } public final Integer one() { return new Integer(1); } }; public static final Arithmetic<Float> FLOAT = new Arithmetic<Float>() { public final Float add(Float a, Float b) { return new Float(a.floatValue() + b.floatValue()); } public final Float sub(Float a, Float b) { return new Float(a.floatValue() - b.floatValue()); } public final Float mul(Float a, Float b) { return new Float(a.floatValue() * b.floatValue()); } public final Float div(Float a, Float b) { return new Float(a.floatValue() / b.floatValue()); } public final Float zero() { return new Float(0.0); } public final Float one() { return new Float(1.0); } }; public static final Arithmetic<Double> DOUBLE = new Arithmetic<Double>() { public final Double add(Double a, Double b) { return new Double(a.doubleValue() + b.doubleValue()); } public final Double sub(Double a, Double b) { return new Double(a.doubleValue() - b.doubleValue()); } public final Double mul(Double a, Double b) { return new Double(a.doubleValue() * b.doubleValue()); } public final Double div(Double a, Double b) { return new Double(a.doubleValue() / b.doubleValue()); } public final Double zero() { return new Double(0.0D); } public final Double one() { return new Double(1.0D); } }; public static final Arithmetic<Long> LONG = new Arithmetic<Long>() { public final Long add(Long a, Long b) { return new Long(a.longValue() + b.longValue()); } public final Long sub(Long a, Long b) { return new Long(a.longValue() - b.longValue()); } public final Long mul(Long a, Long b) { return new Long(a.longValue() * b.longValue()); } public final Long div(Long a, Long b) { return new Long(a.longValue() / b.longValue()); } public final Long zero() { return new Long(0L); } public final Long one() { return new Long(1L); } }; } --- NEW FILE: ArithmeticOperations.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; import org.jdaemon.util.expression.Expression; /** * * @author jonathan */ public class ArithmeticOperations<T> { public final Arithmetic<T> arithmetic; public final Parameter<T> parameter; public BinaryFunction<T,T,T> Add(Parameter<T> a, Parameter<T> b) { return new AbstractBinaryOperator<T,T,T>(Expression.Type.ADD) { public T operate(T a, T b) { return arithmetic.add(a,b); } }; } public UnaryFunction<T,T> Add(T a, Parameter<T> b) { return Operations.BindFirst(Add(parameter, b), a); } public UnaryFunction<T,T> Add(Parameter<T> a, T b) { return Operations.BindSecond(Add(a, parameter), b); } public <U> BinaryFunction<U,T,T> Add(UnaryFunction<U,T> a, Parameter<T> b) { return Operations.ChainFirst(a,Add(parameter,b)); } public <U> BinaryFunction<T,U,T> Add(Parameter<T> a, UnaryFunction<U,T> b) { return Operations.ChainSecond(b,Add(a, parameter)); } public BinaryFunction<T,T,T> Sub(Parameter<T> a, Parameter<T> b) { return new AbstractBinaryOperator<T,T,T>(Expression.Type.SUB) { public T operate(T a, T b) { return arithmetic.sub(a,b); } }; } public UnaryFunction<T,T> Sub(T a, Parameter<T> b) { return Operations.BindFirst(Sub(parameter, b), a); } public UnaryFunction<T,T> Sub(Parameter<T> a, T b) { return Operations.BindSecond(Sub(a, parameter), b); } public <U> BinaryFunction<U,T,T> Sub(UnaryFunction<U,T> a, Parameter<T> b) { return Operations.ChainFirst(a,Sub(parameter,b)); } public <U> BinaryFunction<T,U,T> Sub(Parameter<T> a, UnaryFunction<U,T> b) { return Operations.ChainSecond(b,Sub(a, parameter)); } public BinaryFunction<T,T,T> Mul(Parameter<T> a, Parameter<T> b) { return new AbstractBinaryOperator<T,T,T>(Expression.Type.MUL) { public T operate(T a, T b) { return arithmetic.mul(a,b); } }; } public UnaryFunction<T,T> Mul(T a, Parameter<T> b) { return Operations.BindFirst(Mul(parameter, b), a); } public UnaryFunction<T,T> Mul(Parameter<T> a, T b) { return Operations.BindSecond(Mul(a, parameter), b); } public <U> BinaryFunction<U,T,T> Mul(UnaryFunction<U,T> a, Parameter<T> b) { return Operations.ChainFirst(a,Mul(parameter,b)); } public <U> BinaryFunction<T,U,T> Mul(Parameter<T> a, UnaryFunction<U,T> b) { return Operations.ChainSecond(b,Mul(a, parameter)); } public BinaryFunction<T,T,T> Div(Parameter<T> a, Parameter<T> b) { return new AbstractBinaryOperator<T,T,T>(Expression.Type.DIV) { public T operate(T a, T b) { return arithmetic.div(a,b); } }; } public UnaryFunction<T,T> Div(T a, Parameter<T> b) { return Operations.BindFirst(Div(parameter, b), a); } public UnaryFunction<T,T> Div(Parameter<T> a, T b) { return Operations.BindSecond(Div(a, parameter), b); } public <U> BinaryFunction<U,T,T> Div(UnaryFunction<U,T> a, Parameter<T> b) { return Operations.ChainFirst(a,Div(parameter,b)); } public <U> BinaryFunction<T,U,T> Div(Parameter<T> a, UnaryFunction<U,T> b) { return Operations.ChainSecond(b,Div(a, parameter)); } public ArithmeticOperations(Arithmetic<T> arithmetic, Parameter<T> parameter) { this.arithmetic = arithmetic; this.parameter = parameter; } } --- NEW FILE: Parameter.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; /** Marker class * * @author jonathan */ public class Parameter<T> { public static final Parameter<Integer> INTEGER = new Parameter<Integer>(); public static final Parameter<Float> FLOAT = new Parameter<Float>(); public static final Parameter<Double> DOUBLE = new Parameter<Double>(); public static final Parameter<Long> LONG = new Parameter<Long>(); public static final Parameter<String> STRING = new Parameter<String>(); public static final Parameter<Boolean> BOOLEAN = new Parameter<Boolean>(); } Index: BinaryFunction.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/BinaryFunction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** BinaryFunction.java 29 Jul 2008 22:41:09 -0000 1.1 --- BinaryFunction.java 6 Oct 2008 10:18:38 -0000 1.2 *************** *** 1,5 **** package org.jdaemon.util.functional; ! public interface BinaryFunction<A, B, R> { R operate(A a, B b); --- 1,7 ---- package org.jdaemon.util.functional; ! import org.jdaemon.util.expression.Expression; ! ! public interface BinaryFunction<A, B, R> extends Expression { R operate(A a, B b); Index: CountFunction.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/CountFunction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CountFunction.java 29 Jul 2008 22:41:11 -0000 1.1 --- CountFunction.java 6 Oct 2008 10:18:38 -0000 1.2 *************** *** 1,3 **** --- 1,4 ---- package org.jdaemon.util.functional; + import org.jdaemon.util.expression.*; public class CountFunction<T> implements BinaryFunction<Long, T, Long> { *************** *** 8,10 **** --- 9,19 ---- return a + 1L; } + + public void write(ExpressionWriter writer) throws OutputError { + writer.beginExpression(Expression.Type.FUNC); + writer.writeValue("inc_if_not_null"); + writer.writeParameter("check_null"); + writer.writeParameter("to_increment"); + writer.endExpression(Expression.Type.FUNC); + } } Index: MaxFunction.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/MaxFunction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MaxFunction.java 29 Jul 2008 22:41:11 -0000 1.1 --- MaxFunction.java 6 Oct 2008 10:18:38 -0000 1.2 *************** *** 1,4 **** package org.jdaemon.util.functional; ! import java.util.Comparator; --- 1,4 ---- package org.jdaemon.util.functional; ! import org.jdaemon.util.expression.*; import java.util.Comparator; *************** *** 28,30 **** --- 28,38 ---- return comparator.compare(a, b) > 0 ? a : b; } + + public void write(ExpressionWriter writer) throws OutputError { + writer.beginExpression(Expression.Type.FUNC); + writer.writeValue("max"); + writer.writeParameter("a"); + writer.writeParameter("b"); + writer.endExpression(Expression.Type.FUNC); + } } Index: MinFunction.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/MinFunction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MinFunction.java 29 Jul 2008 22:41:10 -0000 1.1 --- MinFunction.java 6 Oct 2008 10:18:38 -0000 1.2 *************** *** 1,3 **** --- 1,4 ---- package org.jdaemon.util.functional; + import org.jdaemon.util.expression.*; import java.util.Comparator; *************** *** 28,30 **** --- 29,39 ---- return comparator.compare(a, b) < 0 ? a : b; } + + public void write(ExpressionWriter writer) throws OutputError { + writer.beginExpression(Expression.Type.FUNC); + writer.writeValue("min"); + writer.writeParameter("a"); + writer.writeParameter("b"); + writer.endExpression(Expression.Type.FUNC); + } } Index: Operations.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/Operations.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Operations.java 30 Jul 2008 23:41:20 -0000 1.4 --- Operations.java 6 Oct 2008 10:18:38 -0000 1.5 *************** *** 5,13 **** package org.jdaemon.util.functional; import java.util.Collection; - import java.util.List; ! import java.util.ArrayList; /** Library of operations which can be performed on UnaryFunction and BinaryFunction objects. --- 5,13 ---- package org.jdaemon.util.functional; + import org.jdaemon.util.expression.*; import java.util.Collection; import java.util.List; ! /** Library of operations which can be performed on UnaryFunction and BinaryFunction objects. *************** *** 16,20 **** */ public class Operations { ! /** Chain two unary functions together so that the second operates on the result of the first. * --- 16,316 ---- */ public class Operations { ! ! /** Object containing integer arithmetic operators. ! */ ! public static final ArithmeticOperations<Integer> INTEGER = new ArithmeticOperations<Integer>(Arithmetic.INTEGER, Parameter.INTEGER); ! ! /** Object containing floating-point arithmetic operators. ! */ ! public static final ArithmeticOperations<Float> FLOAT = new ArithmeticOperations<Float>(Arithmetic.FLOAT, Parameter.FLOAT); ! ! /** Object containing double-precision floating-point arithmetic operators. ! */ ! public static final ArithmeticOperations<Double> DOUBLE = new ArithmeticOperations<Double>(Arithmetic.DOUBLE, Parameter.DOUBLE); ! ! /** Object containing long integer arithmetic operators. ! */ ! public static final ArithmeticOperations<Long> LONG = new ArithmeticOperations<Long>(Arithmetic.LONG, Parameter.LONG); ! ! /** Template function providing access to a Greater Than comparison operator. ! * ! * @param a dummy parameter specifying type of parameters (value not used - only type in important) ! * @param b dummy parameter specifying type of parameters (value not used - only type in important) ! * @return A BinaryFunction object whose operate method implements the greater than test. ! */ ! public static <T extends Comparable<T>> BinaryFunction<T,T,Boolean> GT(Parameter<T> a, Parameter<T> b) { ! return new AbstractBinaryOperator<T,T,Boolean>(Expression.Type.GT) { ! public Boolean operate(T a, T b) { ! return a.compareTo(b) > 0; ! } ! }; ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> GT(T a, Parameter<T> b) { ! return BindFirst(GT(new Parameter<T>(), b), a); ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> GT(Parameter<T> a, T b) { ! return BindSecond(GT(a, new Parameter<T>()), b); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<U,T,Boolean> GT(UnaryFunction<U,T> a, Parameter<T> b) { ! return ChainFirst(a, GT(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<T,U,Boolean> GT(Parameter<T> a, UnaryFunction<U,T> b) { ! return ChainSecond(b, GT(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> GT(UnaryFunction<U,T> a, T b) { ! return Chain(a, GT(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> GT(T a, UnaryFunction<U,T> b) { ! return Chain(b, GT(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U, V> BinaryFunction<U,V,Boolean> GT(UnaryFunction<U,T> a, UnaryFunction<V,T> b) { ! return ChainSecond(b, GT(a, new Parameter<T>())); ! } ! ! /** Template function providing access to a Less Than comparison operator. ! * ! * @param a dummy parameter specifying type of parameters (value not used - only type in important) ! * @param b dummy parameter specifying type of parameters (value not used - only type in important) ! * @return A BinaryFunction object whose operate method implements the less than test. ! */ ! public static <T extends Comparable<T>> BinaryFunction<T,T,Boolean> LT(Parameter<T> a, Parameter<T> b) { ! return new AbstractBinaryOperator<T,T,Boolean>(Expression.Type.LT) { ! public Boolean operate(T a, T b) { ! return a.compareTo(b) < 0; ! } ! }; ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> LT(T a, Parameter<T> b) { ! return BindFirst(LT(new Parameter<T>(), b), a); ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> LT(Parameter<T> a, T b) { ! return BindSecond(LT(a, new Parameter<T>()), b); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<U,T,Boolean> LT(UnaryFunction<U,T> a, Parameter<T> b) { ! return ChainFirst(a, LT(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<T,U,Boolean> LT(Parameter<T> a, UnaryFunction<U,T> b) { ! return ChainSecond(b, LT(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> LT(UnaryFunction<U,T> a, T b) { ! return Chain(a, LT(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> LT(T a, UnaryFunction<U,T> b) { ! return Chain(b, LT(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U, V> BinaryFunction<U,V,Boolean> LT(UnaryFunction<U,T> a, UnaryFunction<V,T> b) { ! return ChainSecond(b, LT(a, new Parameter<T>())); ! } ! ! /** Template function providing access to a Equality comparison operator. ! * ! * @param a dummy parameter specifying type of parameters (value not used - only type in important) ! * @param b dummy parameter specifying type of parameters (value not used - only type in important) ! * @return A BinaryFunction object whose operate method implements the equality test. ! */ ! public static <T extends Comparable<T>> BinaryFunction<T,T,Boolean> EQ(Parameter<T> a, Parameter<T> b) { ! return new AbstractBinaryOperator<T,T,Boolean>(Expression.Type.EQ) { ! public Boolean operate(T a, T b) { ! return a.compareTo(b) == 0; ! } ! }; ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> EQ(T a, Parameter<T> b) { ! return BindFirst(EQ(new Parameter<T>(), b), a); ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> EQ(Parameter<T> a, T b) { ! return BindSecond(EQ(a, new Parameter<T>()), b); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<U,T,Boolean> EQ(UnaryFunction<U,T> a, Parameter<T> b) { ! return ChainFirst(a, EQ(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<T,U,Boolean> EQ(Parameter<T> a, UnaryFunction<U,T> b) { ! return ChainSecond(b, EQ(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> EQ(UnaryFunction<U,T> a, T b) { ! return Chain(a, EQ(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> EQ(T a, UnaryFunction<U,T> b) { ! return Chain(b, EQ(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U, V> BinaryFunction<U,V,Boolean> EQ(UnaryFunction<U,T> a, UnaryFunction<V,T> b) { ! return ChainSecond(b, EQ(a, new Parameter<T>())); ! } ! ! ! /** Template function providing access to a Greater Than or Equal comparison operator. ! * ! * @param a dummy parameter specifying type of parameters (value not used - only type in important) ! * @param b dummy parameter specifying type of parameters (value not used - only type in important) ! * @return A BinaryFunction object whose operate method implements the greater than or equal test. ! */ ! public static <T extends Comparable<T>> BinaryFunction<T,T,Boolean> GTE(Parameter<T> a, Parameter<T> b) { ! return new AbstractBinaryOperator<T,T,Boolean>(Expression.Type.GTE) { ! public Boolean operate(T a, T b) { ! return a.compareTo(b) >= 0; ! } ! }; ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> GTE(T a, Parameter<T> b) { ! return BindFirst(GTE(new Parameter<T>(), b), a); ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> GTE(Parameter<T> a, T b) { ! return BindSecond(GTE(a, new Parameter<T>()), b); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<U,T,Boolean> GTE(UnaryFunction<U,T> a, Parameter<T> b) { ! return ChainFirst(a, GTE(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<T,U,Boolean> GTE(Parameter<T> a, UnaryFunction<U,T> b) { ! return ChainSecond(b, GTE(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> GTE(UnaryFunction<U,T> a, T b) { ! return Chain(a, GTE(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> GTE(T a, UnaryFunction<U,T> b) { ! return Chain(b, GTE(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U, V> BinaryFunction<U,V,Boolean> GTE(UnaryFunction<U,T> a, UnaryFunction<V,T> b) { ! return ChainSecond(b, GTE(a, new Parameter<T>())); ! } ! ! /** Template function providing access to a Less Than or Equal comparison operator. ! * ! * @param a dummy parameter specifying type of parameters (value not used - only type in important) ! * @param b dummy parameter specifying type of parameters (value not used - only type in important) ! * @return A BinaryFunction object whose operate method implements the less than or equal test. ! */ ! public static <T extends Comparable<T>> BinaryFunction<T,T,Boolean> LTE(Parameter<T> a, Parameter<T> b) { ! return new AbstractBinaryOperator<T,T,Boolean>(Expression.Type.LTE) { ! public Boolean operate(T a, T b) { ! return a.compareTo(b) <= 0; ! } ! }; ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> LTE(T a, Parameter<T> b) { ! return BindFirst(LTE(new Parameter<T>(), b), a); ! } ! ! public static <T extends Comparable<T>> UnaryFunction<T,Boolean> LTE(Parameter<T> a, T b) { ! return BindSecond(LTE(a, new Parameter<T>()), b); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<U,T,Boolean> LTE(UnaryFunction<U,T> a, Parameter<T> b) { ! return ChainFirst(a, LTE(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> BinaryFunction<T,U,Boolean> LTE(Parameter<T> a, UnaryFunction<U,T> b) { ! return ChainSecond(b, LTE(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> LTE(UnaryFunction<U,T> a, T b) { ! return Chain(a, LTE(new Parameter<T>(), b)); ! } ! ! public static <T extends Comparable<T>, U> UnaryFunction<U,Boolean> LTE(T a, UnaryFunction<U,T> b) { ! return Chain(b, LTE(a, new Parameter<T>())); ! } ! ! public static <T extends Comparable<T>, U, V> BinaryFunction<U,V,Boolean> LTE(UnaryFunction<U,T> a, UnaryFunction<V,T> b) { ! return ChainSecond(b, LTE(a, new Parameter<T>())); ! } ! ! public static BinaryFunction<Boolean, Boolean, Boolean> AND(Parameter<Boolean> a, Parameter<Boolean> b) { ! return new AbstractBinaryOperator<Boolean,Boolean,Boolean>(Expression.Type.AND) { ! public Boolean operate(Boolean a, Boolean b) { ! return a && b; ! } ! }; ! } ! ! public static UnaryFunction<Boolean,Boolean> AND(Boolean a, Parameter<Boolean> b) { ! return Operations.BindFirst(AND(Parameter.BOOLEAN, b), a); ! } ! ! public static UnaryFunction<Boolean,Boolean> AND(Parameter<Boolean> a, Boolean b) { ! return Operations.BindSecond(AND(a, Parameter.BOOLEAN), b); ! } ! ! public static <U> BinaryFunction<U,Boolean,Boolean> AND(UnaryFunction<U,Boolean> a, Parameter<Boolean> b) { ! return Operations.ChainFirst(a,AND(Parameter.BOOLEAN,b)); ! } ! ! public static <U> BinaryFunction<Boolean,U,Boolean> AND(Parameter<Boolean> a, UnaryFunction<U,Boolean> b) { ! return Operations.ChainSecond(b,AND(a, Parameter.BOOLEAN)); ! } ! ! public static <T,U> BinaryFunction<T,U,Boolean> AND(UnaryFunction<T, Boolean> a, UnaryFunction<U,Boolean> b) { ! return Operations.ChainSecond(b,AND(a, Parameter.BOOLEAN)); ! } ! ! public static BinaryFunction<Boolean, Boolean, Boolean> OR(Parameter<Boolean> a, Parameter<Boolean> b) { ! return new AbstractBinaryOperator<Boolean,Boolean,Boolean>(Expression.Type.OR) { ! public Boolean operate(Boolean a, Boolean b) { ! return a || b; ! } ! }; ! } ! ! public static UnaryFunction<Boolean,Boolean> OR(Boolean a, Parameter<Boolean> b) { ! return Operations.BindFirst(OR(Parameter.BOOLEAN, b), a); ! } ! ! public static UnaryFunction<Boolean,Boolean> OR(Parameter<Boolean> a, Boolean b) { ! return Operations.BindSecond(OR(a, Parameter.BOOLEAN), b); ! } ! ! public static <U> BinaryFunction<U,Boolean,Boolean> OR(UnaryFunction<U,Boolean> a, Parameter<Boolean> b) { ! return Operations.ChainFirst(a,OR(Parameter.BOOLEAN,b)); ! } ! ! public static <U> BinaryFunction<Boolean,U,Boolean> OR(Parameter<Boolean> a, UnaryFunction<U,Boolean> b) { ! return Operations.ChainSecond(b,OR(a, Parameter.BOOLEAN)); ! } ! ! public static <T,U> BinaryFunction<T,U,Boolean> OR(UnaryFunction<T, Boolean> a, UnaryFunction<U,Boolean> b) { ! return Operations.ChainSecond(b,AND(a, Parameter.BOOLEAN)); ! } ! ! public static UnaryFunction<Boolean, Boolean> NOT(Parameter<Boolean> a) { ! return new AbstractUnaryOperator<Boolean,Boolean>(Expression.Type.NOT) { ! public Boolean operate(Boolean a) { ! return !a; ! } ! }; ! } ! ! public static <U> UnaryFunction<U,Boolean> NOT(UnaryFunction<U,Boolean> a) { ! return Operations.Chain(a,NOT(Parameter.BOOLEAN)); ! } ! ! /** Chain two unary functions together so that the second operates on the result of the first. * *************** *** 28,31 **** --- 324,331 ---- return f2.operate(f1.operate(a)); } + + public void write(ExpressionWriter out) throws OutputError { + f2.write(Expressions.bindParameter(out, f1)); + } }; } *************** *** 42,45 **** --- 342,348 ---- return f2.operate(f1.operate(a,b)); } + public void write(ExpressionWriter out) throws OutputError { + f2.write(Expressions.bindParameter(out, f1)); + } }; } *************** *** 56,59 **** --- 359,365 ---- return f2.operate(f1.operate(a), b); } + public void write(ExpressionWriter out) throws OutputError { + f2.write(Expressions.bindParameter(out, f1)); + } }; } *************** *** 70,73 **** --- 376,382 ---- return f2.operate(a,f1.operate(b)); } + public void write(ExpressionWriter out) throws OutputError { + f2.write(Expressions.bindParameter(out, f1, 2)); + } }; } *************** *** 84,87 **** --- 393,399 ---- return f.operate(a, b); } + public void write(ExpressionWriter out) throws OutputError { + f.write(Expressions.bindParameter(out, a)); + } }; } *************** *** 98,101 **** --- 410,416 ---- return f.operate(a, b); } + public void write(ExpressionWriter out) throws OutputError { + f.write(Expressions.bindParameter(out, b, 2)); + } }; } Index: UnaryFunction.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/UnaryFunction.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** UnaryFunction.java 29 Jul 2008 22:41:08 -0000 1.1 --- UnaryFunction.java 6 Oct 2008 10:18:38 -0000 1.2 *************** *** 1,6 **** package org.jdaemon.util.functional; ! public interface UnaryFunction<A, R> { ! R operate(A a); } --- 1,8 ---- package org.jdaemon.util.functional; ! import org.jdaemon.util.expression.Expression; ! public interface UnaryFunction<A,R> extends Expression { ! ! public R operate(A a); } |
|
From: <je...@23...> - 2008-10-06 10:22:08
|
Update of /cvsroot/era/src/org/jdaemon/test/util/functional In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12494/functional Log Message: Directory /cvsroot/era/src/org/jdaemon/test/util/functional added to the repository |
|
From: <je...@23...> - 2008-10-06 10:22:08
|
Update of /cvsroot/era/src/org/jdaemon/test/util/attribute In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12494/attribute Log Message: Directory /cvsroot/era/src/org/jdaemon/test/util/attribute added to the repository |
|
From: <je...@23...> - 2008-10-06 10:22:08
|
Update of /cvsroot/era/src/org/jdaemon/test/util/expression In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12494/expression Log Message: Directory /cvsroot/era/src/org/jdaemon/test/util/expression added to the repository |
|
From: <je...@23...> - 2008-10-06 10:21:22
|
Update of /cvsroot/era/src/org/jdaemon/util/attribute In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv12195/attribute Modified Files: Attribute.java Log Message: Modifications for ERA v2 - this time it's Generic... Index: Attribute.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/attribute/Attribute.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Attribute.java 30 Jul 2008 23:42:02 -0000 1.2 --- Attribute.java 6 Oct 2008 10:18:38 -0000 1.3 *************** *** 37,41 **** ! protected final UnaryFunction<C,T> accessor = new UnaryFunction<C,T>() { public T operate(C container) { return getValue(container); --- 37,41 ---- ! protected final UnaryFunction<C,T> accessor = new UnaryFunction<C,T>() { public T operate(C container) { return getValue(container); |
|
From: <je...@us...> - 2008-07-30 23:42:08
|
Update of /cvsroot/era/src/org/jdaemon/util/attribute In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv15314 Modified Files: Attributes.java Attribute.java Log Message: CompoundComparator - create composite comparators Index: Attributes.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/attribute/Attributes.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Attributes.java 29 Jul 2008 22:42:38 -0000 1.1 --- Attributes.java 30 Jul 2008 23:42:02 -0000 1.2 *************** *** 17,21 **** /** Utility class Attributes provides similar functions to Collections except ! * enhanced with the functionality provided by the attributes package. * * @author jonathan --- 17,23 ---- /** Utility class Attributes provides similar functions to Collections except ! * enhanced with the functionality provided by the attributes package. Basically, ! * by defining Attribute objects which address individual properties of some object, ! * lists can be sorted and filtered by the values of those properies. * * @author jonathan *************** *** 101,118 **** } public static <T,C> T max(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newMax()); } public static <T,C> T min(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newMin()); } public static <T extends Number & Comparable<? super T>, C> Number sum(Collection<? extends C> collection, NumericAttribute<T,C> attr) { return aggregate(collection, attr.newSum()); } ! public static <T,C> long count(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newCount()).longValue(); ! } } --- 103,149 ---- } + /** Get the maximum value of a property of some objects in a collection. + * + * @param collection + * @param attr + * @return The maximum value of the property addressed by attr within collection. + */ public static <T,C> T max(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newMax()); } + /** Get the minimum value of a property of some objects within a collection. + * + * @param collection + * @param attr + * @return The minimum value of the property addressed by attr within collection. + */ public static <T,C> T min(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newMin()); } + + /** Get the sum of values of a property of some objects within a collection. + * + * @param collection + * @param attr + * @return The sum of values of the property addressed by attr within collection. + */ public static <T extends Number & Comparable<? super T>, C> Number sum(Collection<? extends C> collection, NumericAttribute<T,C> attr) { return aggregate(collection, attr.newSum()); } ! ! /** Get the number of non-null values of a property of some objects within a collection. ! * ! * @param collection ! * @param attr ! * @return The number of non-null values of the property addressed by attr within collection. ! */ public static <T,C> long count(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newCount()).longValue(); ! } ! ! public static <T,C> Collection<C> filter(Collection<? extends C> collection, Attribute<T,C> attr, UnaryFunction<T,Boolean> filter) { ! return Operations.filter(collection, Operations.Chain(attr.accessor, filter)); ! } } Index: Attribute.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/attribute/Attribute.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Attribute.java 29 Jul 2008 22:42:39 -0000 1.1 --- Attribute.java 30 Jul 2008 23:42:02 -0000 1.2 *************** *** 10,20 **** import org.jdaemon.util.functional.*; ! /** An Attribute addresses a value of type T within some container object of class C. ! * * Implementer must provide getValue and setValue methods which extract and ! * set values of this attribute within the data item. The implementer must also provide * a getComparator method, to provide a comparator suitable for comparing values of ! * this attribute. ! * * The implementation provides several useful features. The constants MAX, MIN, * and COUNT are defined, providing binary functions which can be used to compare values of --- 10,21 ---- import org.jdaemon.util.functional.*; ! /** An Attribute addresses a property of type T within some container object of class C. ! * <p> * Implementer must provide getValue and setValue methods which extract and ! * set values of this property within the container object. The implementer must also provide * a getComparator method, to provide a comparator suitable for comparing values of ! * the property. ! * </p> ! * <p> * The implementation provides several useful features. The constants MAX, MIN, * and COUNT are defined, providing binary functions which can be used to compare values of *************** *** 23,27 **** * values of this attribute within the collection, and the number of non-null values of this attribute * within the collection. ! * * * * @author jonathan --- 24,28 ---- * values of this attribute within the collection, and the number of non-null values of this attribute * within the collection. ! * </p> * * * @author jonathan *************** *** 88,94 **** --- 89,135 ---- return new FunctionAccumulator<C,T>(null, Operations.ChainSecond(accessor, MIN)); } + public Accumulator<C,Long> newCount() { return new FunctionAccumulator<C,Long>(null, Operations.ChainSecond(accessor, COUNT)); } + public UnaryFunction<C,Boolean> isGreaterThan(final T operand) { + return new UnaryFunction<C,Boolean>() { + public Boolean operate(C obj) { + return getComparator().compare(getValue(obj), operand) > 0; + } + }; + } + + public UnaryFunction<C,Boolean> isLessThan(final T operand) { + return new UnaryFunction<C,Boolean>() { + public Boolean operate(C obj) { + return getComparator().compare(getValue(obj), operand) < 0; + } + }; + } + + public UnaryFunction<C,Boolean> isGreaterThanOrEqual(final T operand) { + return new UnaryFunction<C,Boolean>() { + public Boolean operate(C obj) { + return getComparator().compare(getValue(obj), operand) >= 0; + } + }; + } + + public UnaryFunction<C,Boolean> isLessThanOrEqual(final T operand) { + return new UnaryFunction<C,Boolean>() { + public Boolean operate(C obj) { + return getComparator().compare(getValue(obj), operand) <= 0; + } + }; + } + + public UnaryFunction<C,Boolean> isEqual(final T operand) { + return new UnaryFunction<C,Boolean>() { + public Boolean operate(C obj) { + return getComparator().compare(getValue(obj), operand) == 0; + } + }; + } } |
|
From: <je...@us...> - 2008-07-30 23:41:24
|
Update of /cvsroot/era/src/org/jdaemon/util/functional In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv15255 Modified Files: Operations.java Added Files: FilterList.java FilterIterator.java FilterCollection.java Log Message: CompoundComparator - create composite comparators --- NEW FILE: FilterList.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; import java.util.AbstractList; import java.util.List; import java.util.ArrayList; /** Lazy filter for lists. * <p> * A list which appears to contain all the elements in some parent collection for * which some filter evaluates to true. Evaluation is lazy so the filtering is * performed only when required (i.e. by get(i) or size() rather than on construction. * </p> * <p> * Filtered elements are cached so a call to get(i) followed by a call to get(j) will * not involve any filtering operation so long as j <= i. A call to size() of necessity * requires that all elements are filtered so after size() is called, no further call to get() * or size() will involve any filtering operation. * </p> * <p> * At the moment the iterator implementation is naive (inherited from AbstractList) so * will presumably call size() and this perform all filtering operations in one fell swoop. * </p> * * @author jonathan */ class FilterList<T> extends AbstractList<T> { private ArrayList<T> cache; private List<? extends T> base; private UnaryFunction<T,Boolean> filter; private int top; /** Create a list containing only those elements from to_filter for which filter.operate(i) * evaluates to true. * * @param to_filter List to filter * @param filter Unary function to choose elements in result list */ public FilterList(List<? extends T> to_filter, UnaryFunction<T,Boolean> filter) { this.base = to_filter; this.filter = filter; this.cache = new ArrayList<T>(); this.top = 0; } /** Get ith element from this list. * * Gets the ith element from the to_filter list for which filter.operate(elem) evaluates * to true. Caches filtered elements, so criteria are evaluated only once for each element. * * @param i Index of element to return */ @Override public T get(int i) { while (i >= cache.size()) { T elem = base.get(top); if (filter.operate(elem)) { cache.add(elem); } top++; } return cache.get(i); } /** Get the number of elements in this list. * * Evaluates to the number of elements in the to_filter list for which filter.operate(elem) * evaluates to true. * * @return the size of this list. */ @Override public int size() { while (top < base.size()) { T elem = base.get(top); if (filter.operate(elem)) { cache.add(elem); } top++; } return cache.size(); } } --- NEW FILE: FilterIterator.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; import java.util.Iterator; /** * * @author jonathan */ public class FilterIterator<T> implements Iterator<T> { private Iterator<? extends T> parent; private T next; private boolean next_ok; private UnaryFunction<T,Boolean> filter; private void move() { do { next = parent.next(); next_ok = filter.operate(next); } while (!next_ok && parent.hasNext()); } public boolean hasNext() { return next_ok; } public T next() { T retval = next; move(); return retval; } public void remove() { throw new UnsupportedOperationException("Not supported yet."); } public FilterIterator(Iterator<? extends T> to_filter, UnaryFunction<T,Boolean> filter_p) { parent = to_filter; filter = filter_p; next_ok = false; next = null; move(); } } --- NEW FILE: FilterCollection.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.functional; import java.util.AbstractCollection; import java.util.Collection; import java.util.Iterator; /** Lazy-filtered collection. * * Note that any changes to the base collection invalidate the FilterCollection. * * @author jonathan * */ class FilterCollection<T> extends AbstractCollection<T> { private Collection<? extends T> base; private UnaryFunction<T,Boolean> filter; private int size; /** Constructor. * * Creates a collection which appears to contain all the elements i of to_filter for * which filter.operate(i) evaluates to true. Note that the constructor does no work and * only the size of the resultant collection is cached. Filter.operate is called once * for every invocation of next() on the iterator returned by this object's iterator method. * * @param to_filter Collection to filter * @param filter Function to determine which elements are in the filtered collection. */ public FilterCollection(Collection<? extends T> to_filter, UnaryFunction<T,Boolean> filter) { this.base = to_filter; this.filter = filter; this.size = -1; // -1 indicates size unknown. } /** Create an iterator for this collection. * * Changes to the to_filter collection provided in the constructor invalidate any iterator * created by this method. Also the returned iterator will raise an exception if remove() is * called. * * @return An iterator object. */ @Override public Iterator<T> iterator() { return new FilterIterator<T>(base.iterator(), filter); } /** Calculate or return cached size. * * Remember: this is a read-only collection. Change that, and you'd have to * clear the size cache every time the colleciton is changed. * * @return Number of elements in base collection for which filter condition is true. */ @Override public int size() { if (size == -1) { size = 0; for (T item : base) { if (filter.operate(item)) size++; } } return size; } } Index: Operations.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/Operations.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Operations.java 29 Jul 2008 22:41:07 -0000 1.3 --- Operations.java 30 Jul 2008 23:41:20 -0000 1.4 *************** *** 9,12 **** --- 9,13 ---- import java.util.List; + import java.util.ArrayList; /** Library of operations which can be performed on UnaryFunction and BinaryFunction objects. *************** *** 151,154 **** } } ! } } --- 152,189 ---- } } ! } ! ! /** Filter a collection. ! * <p> ! * Returns a new collection, containing all the elements of <i>collection</i> for which ! * filter.operate(element) evaluates to true. ! * </p><p> ! * The implementation is lazy; This actual operation is lightweight. The filter critera is evaluated ! * only as elements in the result collection are actually accessed. ! * </p> ! * @param collection Collection to filter ! * @param filter Critera to triage collection ! * @return A collection containing all elements in <I>collection</I> for which filter.operate(elem) is true ! */ ! public static <I> Collection<I> filter(Collection<? extends I> collection, UnaryFunction<I,Boolean> filter) { ! return new FilterCollection<I>(collection, filter); ! } ! ! /** Filter a list. ! * <p> ! * Returns a new list, containing all the elements of <i>list</i> for which ! * filter.operate(element) evaluates to true. ! * </p><p> ! * The implementation is lazy; This actual operation is lightweight. The filter critera is evaluated ! * only as elements in the result list are actually accessed. ! * </p> ! * @param list List to filter ! * @param filter Critera to triage list ! * @return A list containing all elements in <I>list</I> for which filter.operate(elem) is true ! */ ! public static <I> List<I> filter(List<? extends I> list, UnaryFunction<I,Boolean> filter) { ! return new FilterList<I>(list, filter); ! } ! ! } |
|
From: <je...@us...> - 2008-07-29 22:45:52
|
Update of /cvsroot/era/src/org/jdaemon/util/comparator In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv25799 Added Files: CompoundComparator.java Log Message: CompoundComparator - create composite comparators --- NEW FILE: CompoundComparator.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.comparator; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * * @author jonathan */ public class CompoundComparator<T> implements Comparator<T> { List<Comparator<T>> comparators; public int compare(T a, T b) { int result = 0; Iterator<Comparator<T>> i = comparators.iterator(); while (result == 0 && i.hasNext()) { result = i.next().compare(a, b); } return result; } public CompoundComparator(List<Comparator<T>> comp) { comparators = new LinkedList<Comparator<T>>(); comparators.addAll(comp); } } |
Update of /cvsroot/era/src/org/jdaemon/util/attribute In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv24608/attribute Added Files: ComparableAttribute.java Attributes.java NumericAttribute.java AttributeComparator.java Attribute.java Log Message: First commit of attributes package --- NEW FILE: ComparableAttribute.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.attribute; import java.util.Comparator; /** An attribute which has a comparable type * * Basically just implements getComparator() using Comparable.compareTo; Didn't do this in * the base Attribute class because then all Attribute objects would have to be for Comparable * Types - usually (but not always) the case. * * @author jonathan */ public abstract class ComparableAttribute<T extends Comparable<? super T>,C> extends Attribute<T,C> { private static class DefaultComparator<T extends Comparable<? super T>> implements Comparator<T> { public int compare(T a, T b) { return a.compareTo(b); } } public Comparator<T> getComparator() { return new DefaultComparator<T>(); } } --- NEW FILE: Attributes.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.attribute; import org.jdaemon.util.comparator.CompoundComparator; import org.jdaemon.util.functional.*; import java.util.List; import java.util.LinkedList; import java.util.Collections; import java.util.Collection; import java.util.Comparator; /** Utility class Attributes provides similar functions to Collections except * enhanced with the functionality provided by the attributes package. * * @author jonathan */ public class Attributes { /** Converts a list of attributes into a comparator. * * The comparator created will order data items of the type referenced by the * attribute in order of the given attribute values. * * @param attrs A list of attributes of C * @return A comparator implmenting an ordering of C according the the values of the given attributes of C */ public static <C> Comparator<C> newComparator(List<Attribute<?,C>> attrs) { List<Comparator<C>> comparators = new LinkedList<Comparator<C>>(); for (Attribute<?,C> attr : attrs ) { comparators.add(attr.getContainerComparator()); } return new CompoundComparator<C>(comparators); } /** Sort a list, ordering by the given attribute. * * If we have a list of objects of type C, for which we have defined an * attribute attr, then the list will be re-ordered according to the values * referenced by the attribute. * * @param list A list of items of type C * @param attr an attribute of C */ public static <T,C> void sort(List<? extends C> list, Attribute<T,C> attr) { Collections.sort(list, new AttributeComparator<T,C>(attr)); } /** Sort a list, ordering by the given attributes. * * If we have a list of objects of type C, for which we have defined an * attribute attr, then the list will be re-ordered according to the values * referenced by the attributes in <I>attrs</I> * * @param list A list of items of type C * @param attrs A list of attributes of C */ public static <C> void sort(List<? extends C> list, List<Attribute<?,C>> attrs) { Collections.sort(list, newComparator(attrs)); } /** Calculate an aggregate value. * * If attr is an attribute referencing values in C, acc should be one of attr.newMax, newMin, etc. * This method will call acc.accumulate(i) on all elements in <i>collection</i>, so calculating the relavent * aggregate value. * * @param collection * @param acc * @return acc.getResult() after calling acc.accumulate on all elements in collection */ public static <T,C> T aggregate(Collection<? extends C> collection, Accumulator<C,T> acc) { for (C i : collection) { acc.accumulate(i); } return acc.getResult(); } /** Calculate several aggregate values. * * accum acc should be one of attr.newMax, newMin, etc. * This method will call acc.accumulate(i) on all elements in <i>collection</i>, so calculating the relavent * aggregate value. * * @param collection * @param acc * @return acc.getResult() after calling acc.accumulate on all elements in collection */ public static <C> void aggregates(Collection<? extends C> collection, List<Accumulator<C,?>> accumulators) { for (C i : collection) { for (Accumulator<C,?> acc : accumulators) { acc.accumulate(i); } } } public static <T,C> T max(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newMax()); } public static <T,C> T min(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newMin()); } public static <T extends Number & Comparable<? super T>, C> Number sum(Collection<? extends C> collection, NumericAttribute<T,C> attr) { return aggregate(collection, attr.newSum()); } public static <T,C> long count(Collection<? extends C> collection, Attribute<T,C> attr) { return aggregate(collection, attr.newCount()).longValue(); } } --- NEW FILE: NumericAttribute.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.attribute; import org.jdaemon.util.functional.*; /** Attribute representing Numeric (and, by extension, Comparable) types. * * Adds the SUM function to the set of constant functions provided by Attribute, * and the newSum method to the set of Accumulator creators similary provided. * * @author jonathan */ public abstract class NumericAttribute<T extends Number & Comparable<? super T>, C> extends ComparableAttribute<T,C> { public final BinaryFunction<Number,T,Number> SUM; public NumericAttribute() { SUM = new SumFunction<T>(); } public Accumulator<C,Number> newSum() { return new FunctionAccumulator<C,Number>(null, Operations.ChainSecond(accessor, SUM)); } } --- NEW FILE: AttributeComparator.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.attribute; import java.util.Comparator; /** Compares two objects based on the value of some attribute * * @author jonathan */ public class AttributeComparator<T,C> implements Comparator<C> { private Attribute<T,C> attr; public int compare(C a, C b) { return attr.getComparator().compare(attr.getValue(a), attr.getValue(b)); } public AttributeComparator(Attribute<T,C> attr) { this.attr = attr; } } --- NEW FILE: Attribute.java --- /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.jdaemon.util.attribute; import java.util.Comparator; import java.lang.Comparable; import org.jdaemon.util.functional.*; /** An Attribute addresses a value of type T within some container object of class C. * * Implementer must provide getValue and setValue methods which extract and * set values of this attribute within the data item. The implementer must also provide * a getComparator method, to provide a comparator suitable for comparing values of * this attribute. * * The implementation provides several useful features. The constants MAX, MIN, * and COUNT are defined, providing binary functions which can be used to compare values of * this attribute. The methods newMin, newMax, and newCount provide suitable accumulators * which can operate over collections of the container object to calculate the Minimum and Maxmum * values of this attribute within the collection, and the number of non-null values of this attribute * within the collection. * * * * @author jonathan * @param T type of attribute value * @param C type of container object */ public abstract class Attribute<T ,C> { public final BinaryFunction<T,T,T> MAX; public final BinaryFunction<T,T,T> MIN; public final BinaryFunction<Long,T,Long> COUNT; protected final UnaryFunction<C,T> accessor = new UnaryFunction<C,T>() { public T operate(C container) { return getValue(container); } }; public Attribute() { MAX = new MaxFunction<T>(getComparator()); MIN = new MinFunction<T>(getComparator()); COUNT = new CountFunction<T>(); } /** get the value of this Attribute from its container. */ public abstract T getValue(C container); /** set the value of this Attribute in its container. */ public abstract void setValue(T value, C container); /** get a comparator for values of this attribute * * Arg! This should return a shared static instance. F**k type erasure. * * @return a comarator suitable for values of this attribute */ public abstract Comparator<T> getComparator(); /** get a comparator which will compare objects containing this attribute based * on the value of this attribute. * * NOTE: Not totally happy about the existance of this function -- but we need * some way to create a suitable comparator without knowing the type of the attribute * - e.g. when we have a List<Attribute<?,C>> and we want to convert it into a * List<Comparator<C>>. * * Essentially therefore this function achieves nothing beyond the type-safe creation * of the right kind of AttributeComparator. So after type erasure, it's a bit pointless. * * @return */ public Comparator<C> getContainerComparator() { return new AttributeComparator<T,C>(this); } public Accumulator<C,T> newMax() { return new FunctionAccumulator<C,T>(null, Operations.ChainSecond(accessor, MAX)); } public Accumulator<C,T> newMin() { return new FunctionAccumulator<C,T>(null, Operations.ChainSecond(accessor, MIN)); } public Accumulator<C,Long> newCount() { return new FunctionAccumulator<C,Long>(null, Operations.ChainSecond(accessor, COUNT)); } } |
|
From: <je...@us...> - 2008-07-29 22:42:31
|
Update of /cvsroot/era/src/org/jdaemon/util/attribute In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv24592/attribute Log Message: Directory /cvsroot/era/src/org/jdaemon/util/attribute added to the repository |
Update of /cvsroot/era/src/org/jdaemon/util/functional In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv24090 Modified Files: Operations.java Accumulator.java Added Files: SumFunction.java SumAccumulator.java UnaryFunction.java BinaryFunction.java MinFunction.java FunctionAccumulator.java MaxFunction.java CountFunction.java Removed Files: Sum.java Unary.java Max.java Count.java Binary.java Min.java Log Message: Generics functional module a la STL - first commit, a little ropey but apparently functional (ha, ha) --- NEW FILE: SumFunction.java --- package org.jdaemon.util.functional; public class SumFunction<T extends Number> implements BinaryFunction<Number, T, Number> { public Number operate(Number a, T b) { // bit of a bugger that there's no way to optimize this! // really this should implement BinaryFunction<T,T,T> and do Integer, Float, Long, or Double // arithmetic depending on the type of T; oh well. Screw type erasure, anyway. if (a == null) a = new Double(0); if (b == null) return a; return new Double(a.doubleValue() + b.doubleValue()); } } --- NEW FILE: SumAccumulator.java --- package org.jdaemon.util.functional; public class SumAccumulator<T extends Number> implements Accumulator<T, Double> { double sum; public void accumulate(T b) { if (b != null) sum += b.doubleValue(); } public Double getResult() { return sum; } } --- NEW FILE: UnaryFunction.java --- package org.jdaemon.util.functional; public interface UnaryFunction<A, R> { R operate(A a); } --- NEW FILE: BinaryFunction.java --- package org.jdaemon.util.functional; public interface BinaryFunction<A, B, R> { R operate(A a, B b); } --- NEW FILE: MinFunction.java --- package org.jdaemon.util.functional; import java.util.Comparator; public class MinFunction<T> implements BinaryFunction<T, T, T> { private final Comparator<T> comparator; public MinFunction(Comparator<T> comp) { super(); this.comparator = comp; } /** compare a,b * * Note special semantics: * * if a = null, min(a,b) = b; * if b = null, min(a,b) = a; * * @param a * @param b * @return */ public T operate(T a, T b) { if (a == null) return b; if (b == null) return a; return comparator.compare(a, b) < 0 ? a : b; } } --- NEW FILE: FunctionAccumulator.java --- package org.jdaemon.util.functional; public class FunctionAccumulator<T, R> implements Accumulator<T,R> { private R accumulator; private final BinaryFunction<R, T, R> fn; public FunctionAccumulator(R a, final BinaryFunction<R, T, R> f) { super(); accumulator = a; fn = f; } public void accumulate(T t) { accumulator = fn.operate(accumulator, t); } public R getResult() { return accumulator; } } --- NEW FILE: MaxFunction.java --- package org.jdaemon.util.functional; import java.util.Comparator; public class MaxFunction<T> implements BinaryFunction<T, T, T> { private final Comparator<T> comparator; public MaxFunction(Comparator<T> comp) { super(); this.comparator = comp; } /** compare a,b * * Note special semantics: * * if a = null, max(a,b) = b; * if b = null, max(a,b) = a; * * @param a * @param b * @return */ public T operate(T a, T b) { if (a == null) return b; if (b == null) return a; return comparator.compare(a, b) > 0 ? a : b; } } --- NEW FILE: CountFunction.java --- package org.jdaemon.util.functional; public class CountFunction<T> implements BinaryFunction<Long, T, Long> { public Long operate(Long a, T b) { if (a == null) a = 0L; if (b == null) return a; return a + 1L; } } Index: Operations.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/Operations.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Operations.java 19 Feb 2008 19:42:52 -0000 1.2 --- Operations.java 29 Jul 2008 22:41:07 -0000 1.3 *************** *** 8,14 **** import java.util.Collection; ! import java.util.Comparator; ! /** * * @author jonathan --- 8,14 ---- import java.util.Collection; ! import java.util.List; ! /** Library of operations which can be performed on UnaryFunction and BinaryFunction objects. * * @author jonathan *************** *** 16,21 **** public class Operations { ! public static <A, R1, R2> Unary<A,R2> Chain(final Unary<A,R1> f1, final Unary<R1, R2> f2) { ! return new Unary<A,R2>() { public R2 operate(A a) { return f2.operate(f1.operate(a)); --- 16,27 ---- public class Operations { ! /** Chain two unary functions together so that the second operates on the result of the first. ! * ! * @param f1 A unary function ! * @param f2 A unary function ! * @return a new unary function R where R.operate(x) is equivalent to f2.operate(f1.operate(x)) ! */ ! public static <A, R1, R2> UnaryFunction<A,R2> Chain(final UnaryFunction<A,R1> f1, final UnaryFunction<R1, R2> f2) { ! return new UnaryFunction<A,R2>() { public R2 operate(A a) { return f2.operate(f1.operate(a)); *************** *** 24,29 **** } ! public static <A,B, R1, R2> Binary<A,B,R2> Chain(final Binary<A,B,R1> f1, final Unary<R1, R2> f2) { ! return new Binary<A,B,R2>() { public R2 operate(A a, B b) { return f2.operate(f1.operate(a,b)); --- 30,41 ---- } ! /** Chain a unary functions together with a binary function so that the unary on the result of the binary. ! * ! * @param f1 A binary function ! * @param f2 A unary function ! * @return a new binary function R where R.operate(x,y) is equivalent to f2.operate(f1.operate(x,y)) ! */ ! public static <A,B, R1, R2> BinaryFunction<A,B,R2> Chain(final BinaryFunction<A,B,R1> f1, final UnaryFunction<R1, R2> f2) { ! return new BinaryFunction<A,B,R2>() { public R2 operate(A a, B b) { return f2.operate(f1.operate(a,b)); *************** *** 32,37 **** } ! public static <A1, A2, B, R> Binary<A1,B,R> ChainFirst(final Unary<A1, A2> f1, final Binary<A2, B, R> f2) { ! return new Binary<A1,B,R>() { public R operate(A1 a, B b) { return f2.operate(f1.operate(a), b); --- 44,55 ---- } ! /** Chain a unary functions together with a binary function so that the binary on the result of the unary. ! * ! * @param f1 A unary function ! * @param f2 A binary function ! * @return a new binary function R where R.operate(x,y) is equivalent to f2.operate(f1.operate(x), y) ! */ ! public static <A1, A2, B, R> BinaryFunction<A1,B,R> ChainFirst(final UnaryFunction<A1, A2> f1, final BinaryFunction<A2, B, R> f2) { ! return new BinaryFunction<A1,B,R>() { public R operate(A1 a, B b) { return f2.operate(f1.operate(a), b); *************** *** 40,45 **** } ! public static <A, B1, B2, R> Binary<A,B1,R> ChainSecond(final Unary<B1, B2> f1, final Binary<A, B2, R> f2) { ! return new Binary<A,B1,R>() { public R operate(A a, B1 b) { return f2.operate(a,f1.operate(b)); --- 58,69 ---- } ! /** Chain a unary functions together with a binary function so that the binary on the result of the unary. ! * ! * @param f1 A unary function ! * @param f2 A binary function ! * @return a new binary function R where R.operate(x,y) is equivalent to f2.operate(x, f1.operate(y)) ! */ ! public static <A, B1, B2, R> BinaryFunction<A,B1,R> ChainSecond(final UnaryFunction<B1, B2> f1, final BinaryFunction<A, B2, R> f2) { ! return new BinaryFunction<A,B1,R>() { public R operate(A a, B1 b) { return f2.operate(a,f1.operate(b)); *************** *** 47,53 **** }; } ! ! public static <A, B, R> Unary<B,R> BindFirst(final Binary<A,B,R> f, final A a) { ! return new Unary<B,R>() { public R operate(B b) { return f.operate(a, b); --- 71,83 ---- }; } ! ! /** Bind some value to a parameter of a binary function, hence creating a unary function ! * ! * @param f1 A binary function ! * @param a The value to bind ! * @return a new unary function R where R.operate(x) is equivalent to f1.operate(a, x) ! */ ! public static <A, B, R> UnaryFunction<B,R> BindFirst(final BinaryFunction<A,B,R> f, final A a) { ! return new UnaryFunction<B,R>() { public R operate(B b) { return f.operate(a, b); *************** *** 56,61 **** } ! public static <A, B, R> Unary<A,R> BindSecond(final Binary<A,B,R> f, final B b) { ! return new Unary<A,R>() { public R operate(A a) { return f.operate(a, b); --- 86,97 ---- } ! /** Bind some value to a parameter of a binary function, hence creating a unary function ! * ! * @param f1 A binary function ! * @param a The value to bind ! * @return a new unary function R where R.operate(x) is equivalent to f1.operate(x,a) ! */ ! public static <A, B, R> UnaryFunction<A,R> BindSecond(final BinaryFunction<A,B,R> f, final B b) { ! return new UnaryFunction<A,R>() { public R operate(A a) { return f.operate(a, b); *************** *** 63,68 **** }; } ! ! public static <T,I> T accumulate(final Binary<T,I,T> f, Collection<I> collection, T accumulator) { for(I item: collection) { accumulator = f.operate(accumulator, item); --- 99,114 ---- }; } ! ! /** Perform some function on all the values in a collection and return the result. ! * ! * Does accumulator = f.operate(item, accumulator) for every item in a collection, then returns ! * the final value of the accumulator variable. ! * ! * @param f A binary function ! * @param collection A collection of data items ! * @param accumulator Inital value of accumulator variable ! * @return the final value of the accumulator ! */ ! public static <T,I> T accumulate(final BinaryFunction<T,I,T> f, final Collection<I> collection, T accumulator) { for(I item: collection) { accumulator = f.operate(accumulator, item); *************** *** 70,118 **** return accumulator; } ! ! static class Test { ! public String stringv; ! public Integer intv; ! public Test(String a, Integer i) { stringv = a; intv = i; } } ! public static void main(String[] args) { ! ! Unary<Test,String> str_a = new Unary<Test,String>() { ! public String operate(Test t) { ! return t.stringv; } ! }; ! ! Unary<Test,Integer> int_a = new Unary<Test,Integer>() { ! public Integer operate(Test t) { ! return t.intv; ! } ! }; ! ! Binary<Double,Integer,Double> sum = new Sum<Integer>(); ! Binary<String, String, String> max = new Max<String>(String.CASE_INSENSITIVE_ORDER); ! ! Binary<Double,Test,Double> sum_int_a = ChainSecond(int_a, sum); ! Binary<String,Test,String> max_str_a = ChainSecond(str_a, max); ! ! Accumulator<Test, ? extends Object> a1 = new Accumulator<Test, Double>(0.0, sum_int_a); ! Accumulator<Test, ? extends Object> a2 = new Accumulator<Test, String>("", max_str_a); ! ! Test t1 = new Test("abcc", 27); ! Test t2 = new Test("def", 2); ! ! a1.accumulate(t1); ! a2.accumulate(t1); ! ! System.out.println("A1:" + a1.getResult() +",A1:"+ a2.getResult()); ! ! a1.accumulate(t2); ! a2.accumulate(t2); ! ! System.out.println("A1:" + a1.getResult() +",A1:"+ a2.getResult()); ! } ! ! ! } --- 116,154 ---- return accumulator; } ! ! /** Create an accumulator object from a binary function and an initial value. ! * ! * An accumulator object wraps a binary function f(x,y) and an inital value for the accumulator ! * value, a. Each call to the accumulate method with a value i results in accumulator = f(accumulator, i). ! * A call to the getResult method returns the current value of the accumulator. ! * ! * @param f Accumulation function ! * @param value initial value ! * @return An accumulator object. ! */ ! public static <T,I> Accumulator<I,T> newAccumulator(final BinaryFunction<T,I,T> f, T value) { ! return new FunctionAccumulator<I,T>(value,f); } ! /** Perform several functions on all the values in a collection and return the results. ! * <p> ! * Calls accumulate(item) for every accumulator in accumulators for every item in collection. ! * </p><p> ! * For an accumulator acc created with acc=newAccumulator(f,x), acc.getResult() should be equal to ! * accumulate(f, collection, x) once accumulate(Collections.singleList(acc), collection) has been called. ! * In other words, this method allows us to perform several accumulation operations while iterating over ! * a collection only once. ! * </p> ! * ! * ! * @param accumulators A list of accumulator obects ! * @param collection A collection of data items ! */ ! public static <I> void accumulate(List<Accumulator<I,?>> accumulators, final Collection<I> collection) { ! for(I item: collection) { ! for (Accumulator<I,?> accumulator : accumulators) { ! accumulator.accumulate(item); } ! } ! } } Index: Accumulator.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/Accumulator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Accumulator.java 19 Feb 2008 19:42:52 -0000 1.1 --- Accumulator.java 29 Jul 2008 22:41:09 -0000 1.2 *************** *** 1,21 **** ! package org.jdaemon.util.functional; ! ! public class Accumulator<T, R> { ! ! private R accumulator; ! private Binary<R, T, R> fn; ! ! public Accumulator(R a, Binary<R, T, R> f) { ! super(); ! accumulator = a; ! fn = f; ! } ! public void accumulate(T t) { ! accumulator = fn.operate(accumulator, t); ! } ! public R getResult() { ! return accumulator; ! } } --- 1,16 ---- ! /* ! * To change this template, choose Tools | Templates ! * and open the template in the editor. ! */ ! package org.jdaemon.util.functional; ! /** ! * ! * @author jonathan ! */ ! public interface Accumulator<T,R> { ! ! public void accumulate(T t); ! public R getResult(); } --- Sum.java DELETED --- --- Unary.java DELETED --- --- Max.java DELETED --- --- Count.java DELETED --- --- Binary.java DELETED --- --- Min.java DELETED --- |
|
From: <je...@us...> - 2004-07-14 16:13:10
|
Update of /cvsroot/era/src/org/jdaemon/era/helper In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29946/helper Modified Files: AbstractReport.java GroupingImpl.java HelperTypes.java Log Message: Fixing various bugs which showed up in unit testing... mostly just implementing sensible equals operators but also a real problem with AbstractReport's constructor not correctly copying the list parameter. Index: AbstractReport.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/helper/AbstractReport.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** AbstractReport.java 22 Jun 2004 08:23:33 -0000 1.6 --- AbstractReport.java 14 Jul 2004 16:12:44 -0000 1.7 *************** *** 23,32 **** public abstract class AbstractReport implements Report { ! private List levels = new LinkedList(); private boolean detail_flag = true; private Formatting detail_formatting = null; public AbstractReport(List groupings, Formatting detail_formatting) { ! this.levels = levels; this.detail_formatting = detail_formatting; this.detail_flag = detail_formatting != null; --- 23,32 ---- public abstract class AbstractReport implements Report { ! private List levels; private boolean detail_flag = true; private Formatting detail_formatting = null; public AbstractReport(List groupings, Formatting detail_formatting) { ! this.levels = groupings; this.detail_formatting = detail_formatting; this.detail_flag = detail_formatting != null; Index: GroupingImpl.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/helper/GroupingImpl.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** GroupingImpl.java 14 Jun 2004 22:01:07 -0000 1.2 --- GroupingImpl.java 14 Jul 2004 16:12:44 -0000 1.3 *************** *** 198,200 **** --- 198,229 ---- return true; } + + /** Compare one GroupingImpl with another. + * + * GroupingImpls are deemed equal if formattings are equal and the collections of sorts + * and aggregates are both equal. + * + * @param other GroupingImpl to compare. + * @return true if GroupingImpl is the same as this one. + */ + public boolean equals(Object other) { + if (other instanceof GroupingImpl) { + GroupingImpl other_grp = (GroupingImpl)other; + if (this.aggregates.equals(other_grp.aggregates)) { + if (this.sorts.equals(other_grp.sorts)) { + if (this.formatting.equals(other_grp.formatting)) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } } Index: HelperTypes.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/helper/HelperTypes.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** HelperTypes.java 22 Jun 2004 08:23:33 -0000 1.4 --- HelperTypes.java 14 Jul 2004 16:12:44 -0000 1.5 *************** *** 46,49 **** --- 46,50 ---- ERATypes.SORT_LIST.put(representation, "sorts", grouping.getSortsArray()); ERATypes.AGGREGATE_LIST.put(representation, "aggregates", grouping.getAggregatesArray()); + ERATypes.FORMATTING.put(representation, "formatting", grouping.getFormatting()); } }; |
|
From: <je...@us...> - 2004-07-14 16:12:52
|
Update of /cvsroot/era/src/org/jdaemon/era In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29946 Modified Files: Sort.java Log Message: Fixing various bugs which showed up in unit testing... mostly just implementing sensible equals operators but also a real problem with AbstractReport's constructor not correctly copying the list parameter. Index: Sort.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/Sort.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** Sort.java 13 Jun 2004 10:30:26 -0000 1.7 --- Sort.java 14 Jul 2004 16:12:43 -0000 1.8 *************** *** 35,45 **** this.direction = direction; } ! public int getDirection() { return direction; } public String getAttributeName() { return attribute_name; ! } } --- 35,67 ---- this.direction = direction; } ! ! /** Get direction. ! * ! * @return value of direction property ! */ public int getDirection() { return direction; } + /** Get attribute name. + * + * @return value of attribute name property + */ public String getAttributeName() { return attribute_name; ! } ! ! /** Compare two sort objects. ! * ! * @param objother Sort to compare ! * @returns true if attribute_name and direction are equal in this and other sort. ! */ ! public boolean equals(Object obj) { ! if (obj instanceof Sort) { ! Sort other = (Sort)obj; ! return (this.direction == other.direction && this.attribute_name.equals(other.attribute_name)); ! } else { ! return false; ! } ! } } |
Update of /cvsroot/era/src/org/jdaemon/era/grml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27794 Modified Files: CellAttributesWriter.java CellWriter.java ElementWriter.java GRMLReport.java GRMLTypes.java GenericCellAttributesWriter.java GenericCellWriter.java GenericElementCollectionWriter.java GenericElementWriter.java GenericFieldWriter.java GenericGridAttributesWriter.java GenericGridWriter.java GenericRecordWriter.java GenericRecordsetWriter.java GridAttributesWriter.java RecordWriter.java TestGRMLReport.java Added Files: FieldWriter.java GenericHeaderWriter.java HeaderWriter.java RecordWriterDescriptor.java Log Message: Finally got GRMLReport through its unit tests for import/export from a DataRepresentation. Main change has been to change the way that GridAttributes elements are added to a report. GridAttributes are now generated by Grid elements. This removes a considerable redundancy in GRMLReport which became glaringly obvious while writing the test cases. --- NEW FILE: FieldWriter.java --- /* * CellWriter.java * * Copyright (C) 2004 [iQuality Ltd.] * This program is distributed under the terms of the Lesser GNU General Public * License (v2 or later) per the included COPYING.txt file, or see www.fsf.org. * */ package org.jdaemon.era.grml; import org.jdaemon.six.ReportBuilder; import org.jdaemon.six.BuildException; /** Interface for writers which output field elements. * <P> * The GRML DTD specifies two elements types which represent the fundamental data items on a * report: field and cell. Field elements are can be arranged freely in nested groups, wheras * cell objects are contained within a rigidly defined grid. * </P><P> * The FieldWriter interface is used to write field elements within a group. In most cases the premade * GenericFieldWriter implementation should be sufficient. * </P><P> * FuekdWriter should be implemnted to output well-formed field elements to a ReportBuilder. * <P> * @author Jonathan Essex */ public interface FieldWriter extends RecordElementWriter { /** Write field to a builder. * * @param record containing data to write * @param builder builder used to output data */ public void write( Record record, ReportBuilder builder ) throws BuildException; } --- NEW FILE: GenericHeaderWriter.java --- /* * GenericHeaderWriter.java * * Created on July 13, 2004, 9:06 PM */ package org.jdaemon.era.grml; import org.jdaemon.six.ReportBuilder; import org.jdaemon.six.BuildException; import java.util.HashSet; import java.util.Iterator; /** HeaderWriter implementation. * * @author Jonathan Essex */ public class GenericHeaderWriter implements HeaderWriter { private HashSet grid_attributes; /** Creates a new instance of GenericHeaderWriter */ public GenericHeaderWriter() { this.grid_attributes = new HashSet(); } /** add a GridAttributes section to the header. * * @param writer GridAttributesWriter to add */ public void addGridAttributesWriter(GridAttributesWriter writer) { grid_attributes.add(writer); } /** Write header out to buider. * * @param builder Builder to output to. */ public void write(ReportBuilder builder) throws BuildException { Iterator i = grid_attributes.iterator(); while (i.hasNext()) ((GridAttributesWriter)i.next()).write(builder); } } --- NEW FILE: HeaderWriter.java --- /* * HeaderWriter.java * * Created on July 13, 2004, 8:50 PM */ package org.jdaemon.era.grml; import org.jdaemon.six.ReportBuilder; import org.jdaemon.six.BuildException; /** Inteface for gathering documents fragments for report header. * * @author Jonathan Essex */ public interface HeaderWriter { /** Add a grid attributes section to the report header. * * @param writer Writer for grid attributes section */ public void addGridAttributesWriter(GridAttributesWriter writer); /** Write resulting header to report builder. * * @param builder Builder to output header to */ public void write(ReportBuilder builder) throws BuildException; } --- NEW FILE: RecordWriterDescriptor.java --- /* * RecordWriterDescriptor.java * * Created on July 7, 2004, 6:31 PM */ package org.jdaemon.era.grml; import org.jdaemon.era.*; import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.Iterator; import java.util.Collections; /** Class describing a RecordWriter. * * Note - maybe we could have a public interface here adding only the getGridWriters method * to the base FormattingDescriptor. Thing about this before being tempted to make this impementation * public. * * @author Jonathan Essex */ class RecordWriterDescriptor { private Set required_aggregates; private Set required_attributes; private Set grid_attributes_writers; /** Creates a new instance of RecordWriterDescriptor. */ public RecordWriterDescriptor() { required_aggregates = new HashSet(); required_attributes = new HashSet(); grid_attributes_writers = new HashSet(); } /** Get set of aggregates required by RecordWriter. * * @return a set of Aggregate objects indicating which aggregate calculations the RecordWriter requires */ public Set getRequiredAggregates() { return Collections.unmodifiableSet(required_aggregates); } /** Get set of data attributes required by RecordWriter. * * @return a set of Strings indicating which data values are required by the RecordWriter */ public Set getRequiredDataAttributes() { return Collections.unmodifiableSet(required_attributes); } /** Get the set of grid writers used by this RecordWriter. * * Note - could use a GridWriter interface here. * * @return a set of GenericGridWriter objects that are used by this RecordWriter */ public Set getGridAttributesWriters() { return Collections.unmodifiableSet(grid_attributes_writers); } /** Adds an aggregate to the required set. * * Used when building the a RecordWriterDescriptor from a record. * * @param agg Aggregate to add to required set. */ public void requireAggregate(Aggregate agg) { required_aggregates.add(agg); } /** Adds a data attribute to the required set. * * Used when building the a RecordWriterDescriptor from a record. * * @param attr Attribute to add to required set. */ public void requireDataAttribute(String attr) { required_attributes.add(attr); } /** Adds a GridWriter to the use set. * * Used when building the a RecordWriterDescriptor from a record. * * @param writer GenericGridWriter to add to use set. */ public void registerGridAttributesWriter(GridAttributesWriter writer) { grid_attributes_writers.add(writer); } /** Add grid attributes to a header. */ public void registerHeaderElements(HeaderWriter header) { Iterator i = grid_attributes_writers.iterator(); while (i.hasNext()) header.addGridAttributesWriter((GridAttributesWriter)i.next()); } } Index: CellAttributesWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/CellAttributesWriter.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** CellAttributesWriter.java 26 May 2004 14:45:34 -0000 1.2 --- CellAttributesWriter.java 14 Jul 2004 16:05:40 -0000 1.3 *************** *** 9,12 **** --- 9,15 ---- package org.jdaemon.era.grml; + import org.jdaemon.six.ReportBuilder; + import org.jdaemon.six.BuildException; + /** Interface for adding cell attributes elements to a grid-attributes element. * <P> *************** *** 23,27 **** * @author Jonathan Essex */ ! public interface CellAttributesWriter extends ElementWriter { ! } --- 26,35 ---- * @author Jonathan Essex */ ! public interface CellAttributesWriter { ! /** Write cell attributes out to a builder ! * ! * @param builder Builder to output cell attributes to. ! */ ! public void write(ReportBuilder builder) throws BuildException; ! }; Index: CellWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/CellWriter.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CellWriter.java 14 Jun 2004 22:02:24 -0000 1.3 --- CellWriter.java 14 Jul 2004 16:05:44 -0000 1.4 *************** *** 26,30 **** * @author Jonathan Essex */ ! public interface CellWriter extends ElementWriter { /** Write cell to a builder. --- 26,30 ---- * @author Jonathan Essex */ ! public interface CellWriter extends RecordElementWriter { /** Write cell to a builder. *************** *** 34,38 **** */ public void write( Record record, ! ReportBuilder builder ) throws BuildException; } --- 34,45 ---- */ public void write( Record record, ! ReportBuilder builder ) throws BuildException; ! ! ! /** Get writer for cell attributes. ! * ! * @return A CellAttributesWriter ! */ ! public CellAttributesWriter getCellAttributesWriter(); } Index: ElementWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/ElementWriter.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ElementWriter.java 13 Jun 2004 21:05:18 -0000 1.4 --- ElementWriter.java 14 Jul 2004 16:05:44 -0000 1.5 *************** *** 18,22 **** * GenericElementCollectionWriter to be inherited by various distinct types. * </p><p> ! * The interfaces RecordWriter, CellWriter, CellAttributesWriter and RecordElementWriter are all subclasses * of this interface but outisde of this package should always be treated as distinct types. Hence * this interface is not public and should not be made so. --- 18,22 ---- * GenericElementCollectionWriter to be inherited by various distinct types. * </p><p> ! * The interfaces RecordWriter, CellWriter, and RecordElementWriter are all subclasses * of this interface but outisde of this package should always be treated as distinct types. Hence * this interface is not public and should not be made so. *************** *** 33,54 **** void write(Record record, ReportBuilder builder) throws BuildException; ! /** Add any Aggregates required to a list. * ! * The write method of any ElementWriter may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which aggregate calculations are required by this writer. * ! * @param list A set object to which Aggregate objects are added. */ ! public void buildRequiredAggregatesSet(Set list); - /** Add any data attributes required to a list. - * - * The write method of any ElementWriter may require certain attributes and aggregate - * calculations to exist in the Record objects supplied to the write method. This method - * provides a way to discover which data attributes are required by this writer. - * - * @param list A set object to which names of data attributes are added as String objects. - */ - public void buildRequiredDataAttributesSet(Set list); } --- 33,43 ---- void write(Record record, ReportBuilder builder) throws BuildException; ! /** Build RecordWriterDescriptor. * ! * Builds descriptor which is subsequently used for writing headers etc. * ! * @param descriptor object which subclasses can use to build metadata. */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor); } Index: GRMLReport.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GRMLReport.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** GRMLReport.java 22 Jun 2004 08:23:32 -0000 1.9 --- GRMLReport.java 14 Jul 2004 16:05:44 -0000 1.10 *************** *** 23,27 **** import org.xml.sax.ContentHandler; ! import java.util.TreeMap; import java.util.List; import java.util.ArrayList; --- 23,27 ---- import org.xml.sax.ContentHandler; ! import java.util.HashSet; import java.util.List; import java.util.ArrayList; *************** *** 99,104 **** } - private TreeMap grid_attributes = new TreeMap(); private String class_id; /** Get an XML view of a cube. --- 99,105 ---- } private String class_id; + private HeaderWriter header_writer; + /** Get an XML view of a cube. *************** *** 131,156 **** } ! /** Write out grid attributes for this report to builder. ! * ! * Writes any grid-attributes elements (previously set with setGridAttributes) ! * for this report to the supplied builder. ! * ! * @param builder to output grid-attributes element to. ! * @throws BuildException on any error writing to builder. */ ! private void writeGridAttributes(ReportBuilder builder) throws BuildException { ! Iterator i = grid_attributes.values().iterator(); ! while (i.hasNext()) { ! ((GridAttributesWriter)i.next()).write(null, builder); ! } } - /** Set the class attributes for cells in grid elements of a given class. - * - * @param grid_attr A GridAttributesWriter object. - */ - public void addGridAttributes(GridAttributesWriter grid_attr) { - grid_attributes.put(grid_attr.getClassAttribute(), grid_attr); - } /** Apply transformations to a builder. --- 132,150 ---- } ! /** Get the header writer for this report. */ ! public HeaderWriter getHeaderWriter() { ! if (header_writer == null) { ! header_writer = new GenericHeaderWriter(); ! Iterator i = groupingsList().iterator(); ! while (i.hasNext()) { ! Grouping grouping = (Grouping)i.next(); ! ((RecordWriter)grouping.getFormatting()).registerHeaderElements(header_writer); ! } ! } ! ((RecordWriter)getDetailFormatting()).registerHeaderElements(header_writer); ! return header_writer; } /** Apply transformations to a builder. *************** *** 186,190 **** private void writeReport(Cube cube, ReportBuilder builder) throws BuildException { builder.startReport(cube.getClass().toString(), AttributeList.EMPTY); ! writeGridAttributes(builder); applyTransformations(groupingsList().iterator(), builder).writeObject(cube); builder.endReport(); --- 180,184 ---- private void writeReport(Cube cube, ReportBuilder builder) throws BuildException { builder.startReport(cube.getClass().toString(), AttributeList.EMPTY); ! getHeaderWriter().write(builder); applyTransformations(groupingsList().iterator(), builder).writeObject(cube); builder.endReport(); *************** *** 215,225 **** /** Construct a new GRMLReport object */ ! public GRMLReport(String class_id, Grouping[] groupings, RecordWriter detail_writer) { super(new ArrayList(Arrays.asList(groupings)), detail_writer); this.class_id = class_id; } public GRMLReport(String class_id) { this.class_id = class_id; } } --- 209,239 ---- /** Construct a new GRMLReport object */ ! public GRMLReport(String class_id, Grouping[] groupings, RecordWriter detail_writer) { super(new ArrayList(Arrays.asList(groupings)), detail_writer); this.class_id = class_id; } + /** Construct an empty GRMLReport object + */ public GRMLReport(String class_id) { this.class_id = class_id; } + + private static boolean equal(Object o1, Object o2) { + return (o1 == null || o2 == null) ? o1 == o2 : o1.equals(o2); + } + + /** Compare this report with another. + * + * @return true if <code>other</code> is a GRMLReport which is identical to this one. + */ + public boolean equals(Object other) { + if (other instanceof GRMLReport) { + GRMLReport other_rp = (GRMLReport)other; + return ( equal(this.class_id, other_rp.class_id) + && equal(this.getDetailFormatting(), other_rp.getDetailFormatting()) + && equal(this.groupingsList(), other_rp.groupingsList())); + } + return false; + } } Index: GRMLTypes.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GRMLTypes.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** GRMLTypes.java 22 Jun 2004 08:23:32 -0000 1.4 --- GRMLTypes.java 14 Jul 2004 16:05:44 -0000 1.5 *************** *** 11,14 **** --- 11,15 ---- package org.jdaemon.era.grml; import org.jdaemon.era.*; + import org.jdaemon.era.helper.HelperTypes; import org.jdaemon.util.AttributeList; import org.jdaemon.util.data.*; *************** *** 18,22 **** import java.text.Format; ! /** Repository for Type objects in top-level ERA package. * * @author Jonathan Essex --- 19,23 ---- import java.text.Format; ! /** Repository for Type objects in GRML package. * * @author Jonathan Essex *************** *** 103,113 **** public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { Object value = representation.getAttribute("value"); if (value != null) { ! return new GenericCellWriter(value); } else { int attribute_type = convertAttributeType(representation.getAttribute("type")); String attribute_name = representation.getAttribute("attribute"); Format format = (Format)FormatTypes.FORMAT.get(representation,"format"); ! return new GenericCellWriter(attribute_type, attribute_name, format); } } --- 104,117 ---- public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { Object value = representation.getAttribute("value"); + String span_string = representation.getAttribute("span"); + String class_id = representation.getAttribute("class_id"); + int span = span_string == null ? 1 : Integer.parseInt(span_string); if (value != null) { ! return new GenericCellWriter(class_id, span, value); } else { int attribute_type = convertAttributeType(representation.getAttribute("type")); String attribute_name = representation.getAttribute("attribute"); Format format = (Format)FormatTypes.FORMAT.get(representation,"format"); ! return new GenericCellWriter(class_id, span, attribute_type, attribute_name, format); } } *************** *** 240,297 **** }; - /** Type for GenericCellAttributesWriter objects. - */ - public static final Type GENERIC_CELL_ATTRIBUTES_WRITER = new Type("CellAttributes", GenericCellAttributesWriter.class) { - - /** Reads a GenericCellAttributesWriter object from a DataRepresentation. - * - * @param representation DataRepresentation from which to read the GenericCellAttributesWriter object - * @return A new CellAttributesWriter object - */ - public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { - String class_id = representation.getAttribute("class"); - String span = representation.getAttribute("span"); - return new GenericCellAttributesWriter(class_id, span == null ? null : Integer.valueOf(span)); - } - - /** Writes a GenericCellAttributesWriter object to some DataRepresentation. - * - * @param representation DataRepresentation to which the GenericCellAttributesWriter object will be written - * @param object GenericCellAttributesWriter object to be written to <I>representation</I> - */ - public void write(DataRepresentation representation, Object object) throws WriteError { - GenericCellAttributesWriter writer = (GenericCellAttributesWriter)object; - representation.setAttribute("class", writer.getClassAttribute()); - if (writer.getSpanAttribute() != null) representation.setAttribute("span", writer.getSpanAttribute().toString()); - } - }; - - /** Type for GenericGridAttributesWriter objects. - */ - public static final Type GENERIC_GRID_ATTRIBUTES_WRITER = new Type("GridAttributes", GenericGridAttributesWriter.class) { - - /** Reads a GenericGridAttributesWriter object from a DataRepresentation. - * - * @param representation DataRepresentation from which to read the GenericGridAttributesWriter object - * @return A new GenericGridAttributesWriter object - */ - public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { - String class_id = representation.getAttribute("class"); - CellAttributesWriter[] elements = (GenericCellAttributesWriter[])CELL_ATTRIBUTES_ARRAY.get(representation, "elements"); - return new GenericGridAttributesWriter(class_id, elements); - } - - /** Writes a GenericGridAttributesWriter object to some DataRepresentation. - * - * @param representation DataRepresentation to which the GenericGridAttributesWriter object will be written - * @param object GenericGridAttributesWriter object to be written to <I>representation</I> - */ - public void write(DataRepresentation representation, Object object) throws WriteError { - GenericGridAttributesWriter writer = (GenericGridAttributesWriter)object; - representation.setAttribute("class", writer.getClassAttribute()); - CELL_ATTRIBUTES_LIST.put(representation, "elements", writer.listElements()); - } - }; - /** Type for GRMLReportWriter objects. */ --- 244,247 ---- *************** *** 338,349 **** */ public static final Type CELL_LIST = Types.listOf(GENERIC_CELL_WRITER); - - /** Array type for cell attributes elements. - */ - public static final Type CELL_ATTRIBUTES_ARRAY = Types.arrayOf(GENERIC_CELL_ATTRIBUTES_WRITER); - - /** List type for cell attribute elements. - */ - public static final Type CELL_ATTRIBUTES_LIST = Types.listOf(GENERIC_CELL_ATTRIBUTES_WRITER); } --- 288,291 ---- Index: GenericCellAttributesWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericCellAttributesWriter.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** GenericCellAttributesWriter.java 22 Jun 2004 08:23:32 -0000 1.7 --- GenericCellAttributesWriter.java 14 Jul 2004 16:05:44 -0000 1.8 *************** *** 32,36 **** * @author Jonathan Essex */ ! public class GenericCellAttributesWriter extends GenericElementWriter implements CellAttributesWriter { private String class_id; --- 32,36 ---- * @author Jonathan Essex */ ! public class GenericCellAttributesWriter implements CellAttributesWriter { private String class_id; *************** *** 42,49 **** * @param span Cell span */ ! public GenericCellAttributesWriter(String class_id, Integer span) { ! super(null); this.class_id = class_id; ! this.span = span; } --- 42,48 ---- * @param span Cell span */ ! public GenericCellAttributesWriter(String class_id, int span) { this.class_id = class_id; ! this.span = span == 1 ? null : new Integer(span); } *************** *** 53,77 **** */ public GenericCellAttributesWriter(String class_id) { ! this(class_id, null); } ! /** Send end element event to builder. ! * ! * @param builder ReportBuilder to send start element event to ! * ! */ ! protected void endElement(ReportBuilder builder) throws BuildException { ! builder.endCellAttributes(); ! } ! ! /** Send start element event to builder. ! * ! * @param builder ReportBuilder to send end element event to ! * ! */ ! protected void startElement(ReportBuilder builder) throws BuildException { AttributeList list = AttributeList.EMPTY; if (span != null) list = list.addAttribute("span", span); builder.startCellAttributes(class_id, list); } --- 52,63 ---- */ public GenericCellAttributesWriter(String class_id) { ! this(class_id, 1); } ! public void write(ReportBuilder builder) throws BuildException { AttributeList list = AttributeList.EMPTY; if (span != null) list = list.addAttribute("span", span); builder.startCellAttributes(class_id, list); + builder.endCellAttributes(); } Index: GenericCellWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericCellWriter.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** GenericCellWriter.java 21 Jun 2004 16:43:26 -0000 1.6 --- GenericCellWriter.java 14 Jul 2004 16:05:44 -0000 1.7 *************** *** 36,39 **** --- 36,41 ---- */ public class GenericCellWriter extends GenericElementWriter implements CellWriter { + + private CellAttributesWriter attrs; /** Creates a new instance of GenericCellWriter to write out some static data. *************** *** 43,51 **** * writeObject method. * </P> ! * @param class_id Class Id for fields written by this writer * @param value Value to write in field. */ ! public GenericCellWriter(Object value) { super(value); } --- 45,55 ---- * writeObject method. * </P> ! * @param class_id Class Id for cells written by this writer ! * @param span No of horizontal 'units' this cell occupies in the global grid * @param value Value to write in field. */ ! public GenericCellWriter(String class_id, int span, Object value) { super(value); + attrs = new GenericCellAttributesWriter(class_id, span); } *************** *** 58,67 **** * </P> * @param class_id Class Id for fields written by this writer * @param attribute_name Name of attribute to write in this field * @param attribute_type Type of attribute to write in this field (One of Record.DATA, MAX, MIN, SUM, COUNT) * @param format format to use to write field */ ! public GenericCellWriter(int attribute_type, String attribute_name, Format format) { super(attribute_type, attribute_name, format); } --- 62,73 ---- * </P> * @param class_id Class Id for fields written by this writer + * @param span No of horizontal 'units' this cell occupies in the global grid * @param attribute_name Name of attribute to write in this field * @param attribute_type Type of attribute to write in this field (One of Record.DATA, MAX, MIN, SUM, COUNT) * @param format format to use to write field */ ! public GenericCellWriter(String class_id, int span, int attribute_type, String attribute_name, Format format) { super(attribute_type, attribute_name, format); + attrs = new GenericCellAttributesWriter(class_id, span); } *************** *** 73,81 **** * </P> * * @param class_id Class Id for fields written by this writer * @param attribute_name Name of attribute to write in this field * @param attribute_type Type of attribute to write in this field (One of Record.DATA, MAX, MIN, SUM, COUNT) */ ! public GenericCellWriter(int attribute_type, String attribute_name) { ! this(attribute_type, attribute_name, null); } --- 79,88 ---- * </P> * * @param class_id Class Id for fields written by this writer + * @param span No of horizontal 'units' this cell occupies in the global grid * @param attribute_name Name of attribute to write in this field * @param attribute_type Type of attribute to write in this field (One of Record.DATA, MAX, MIN, SUM, COUNT) */ ! public GenericCellWriter(String class_id, int span, int attribute_type, String attribute_name) { ! this(class_id, span, attribute_type, attribute_name, null); } *************** *** 109,111 **** --- 116,128 ---- } } + + /** Get writer for cell attributes. + * + * @return A CellAttributesWriter + */ + public CellAttributesWriter getCellAttributesWriter() { + return attrs; + } + + } Index: GenericElementCollectionWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericElementCollectionWriter.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** GenericElementCollectionWriter.java 13 Jun 2004 21:05:19 -0000 1.5 --- GenericElementCollectionWriter.java 14 Jul 2004 16:05:44 -0000 1.6 *************** *** 75,109 **** } ! /** Add any Aggregates required to a list. ! * ! * The write method of any ElementWriter may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which aggregate calculations are required by this writer. * ! * @param list A set object to which Aggregate objects are added. */ ! public void buildRequiredAggregatesSet(Set list) { Iterator i = elements.iterator(); while (i.hasNext()) { ! ((ElementWriter)i.next()).buildRequiredAggregatesSet(list); } } ! ! /** Add any data attributes required to a list. ! * ! * The write method of any ElementWriter may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which data attributes are required by this writer. ! * ! * @param list A set object to which names of data attributes are added as String objects. ! */ ! public void buildRequiredDataAttributesSet(Set list) { ! Iterator i = elements.iterator(); ! while (i.hasNext()) { ! ((ElementWriter)i.next()).buildRequiredDataAttributesSet(list); ! } ! } ! ! /** Write elements to a builder. * --- 75,89 ---- } ! /** Add information from contained elements to a descriptor. * ! * @param descriptor Descriptor to which we add the necessary information. */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor) { Iterator i = elements.iterator(); while (i.hasNext()) { ! ((ElementWriter)i.next()).buildRecordWriterDescriptor(descriptor); } } ! /** Write elements to a builder. * Index: GenericElementWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericElementWriter.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** GenericElementWriter.java 22 Jun 2004 08:23:32 -0000 1.8 --- GenericElementWriter.java 14 Jul 2004 16:05:44 -0000 1.9 *************** *** 35,42 **** * implementations may ignore the record and go elsewhere to find data. * </P><P> ! * This interface may be implemented in order to provide new DataSources (for example, * 'current time') for cells and fields. * </P><P> ! * Note also that all current implemnetations of DataSource are basically constant * obejects which, once constructed, do not change. Implementers of new DataSources * are advised to follow this pattern. --- 35,42 ---- * implementations may ignore the record and go elsewhere to find data. * </P><P> ! * This interface may be implemented in order to provide new DataSources (for example, * 'current time') for cells and fields. * </P><P> ! * Note also that all current implemnetations of DataSource are basically constant * obejects which, once constructed, do not change. Implementers of new DataSources * are advised to follow this pattern. *************** *** 57,80 **** Object get(Record data); ! /** Add any Aggregates required to a list. ! * ! * The write method of any ElementWriter may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which aggregate calculations are required by this writer. ! * ! * @param list A set object to which Aggregate objects are added. ! */ ! public void buildRequiredAggregatesSet(Set list); ! ! /** Add any data attributes required to a list. ! * ! * The write method of any ElementWriter may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which data attributes are required by this writer. * ! * @param list A set object to which names of data attributes are added as String objects. */ ! public void buildRequiredDataAttributesSet(Set list); ! } --- 57,65 ---- Object get(Record data); ! /** Build metadata. * ! * @param descriptor Object to accumulate metadata */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor); } *************** *** 115,142 **** public int getAttributeType() { return attribute_type; - } - - /** Add any Aggregates required to a list. - * - * The write method of any ElementWriter may require certain attributes and aggregate - * calculations to exist in the Record objects supplied to the write method. This method - * provides a way to discover which aggregate calculations are required by this writer. - * - * @param list A set object to which Aggregate objects are added. - */ - public void buildRequiredAggregatesSet(Set list) { - if (attribute_type != Record.DATA) list.add(new Aggregate(attribute_name, attribute_type)); } ! /** Add any data attributes required to a list. ! * ! * The write method of any ElementWriter may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which data attributes are required by this writer. * ! * @param list A set object to which names of data attributes are added as String objects. */ ! public void buildRequiredDataAttributesSet(Set list) { ! if (attribute_type != Record.DATA) list.add(attribute_name); } --- 100,112 ---- public int getAttributeType() { return attribute_type; } ! /** Build metatdata * ! * @param descriptor Object to accumulate metadata */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor) { ! if (attribute_type != Record.DATA) descriptor.requireAggregate(new Aggregate(attribute_name, attribute_type)); ! if (attribute_type != Record.DATA) descriptor.requireDataAttribute(attribute_name); } *************** *** 149,154 **** if (other instanceof AttributeDataSource) { AttributeDataSource other_ds = (AttributeDataSource)other; ! return ( this.attribute_type == other_ds.attribute_type ! && this.attribute_name.equals(other_ds.attribute_name)); } else { return false; --- 119,124 ---- if (other instanceof AttributeDataSource) { AttributeDataSource other_ds = (AttributeDataSource)other; ! return ( this.attribute_type == other_ds.attribute_type ! && this.attribute_name.equals(other_ds.attribute_name)); } else { return false; *************** *** 174,193 **** this.value = value; } - /** Add any Aggregates required to a list. - * - * Does nothing as a StaticDataSource requires no data from a record. - * - * @param list A set object to which Aggregate objects are added. - */ - public void buildRequiredAggregatesSet(Set list) { - } ! /** Add any data attributes required to a list. ! * ! * Does nothing as a StaticDataSource requires no data from a record. * ! * @param list A set object to which names of data attributes are added as String objects. */ ! public void buildRequiredDataAttributesSet(Set list) { } --- 144,153 ---- this.value = value; } ! /** Build metatdata * ! * @param descriptor Object to accumulate metadata */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor) { } *************** *** 199,205 **** * the various subclasses of GenericElementWriter (including GenericFieldWriter * and GenericCellWriter). An awful lot of code assumes that, once created, ! * a GenericFieldWriter remeains constant. * </P> ! * @return the value */ public Object getValue() { --- 159,165 ---- * the various subclasses of GenericElementWriter (including GenericFieldWriter * and GenericCellWriter). An awful lot of code assumes that, once created, ! * a GenericFieldWriter remeains constant. * </P> ! * @return the value */ public Object getValue() { *************** *** 298,323 **** } ! /** Add any Aggregates required to a list. ! * ! * The write method of this class may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which aggregate calculations are required by this writer. ! * ! * @param list A set object to which Aggregate objects are added. ! */ ! public void buildRequiredAggregatesSet(Set list) { ! datasource.buildRequiredAggregatesSet(list); ! } ! ! /** Add any data attributes required to a list. ! * ! * The write method of this class may require certain attributes and aggregate ! * calculations to exist in the Record objects supplied to the write method. This method ! * provides a way to discover which data attributes are required by this writer. * ! * @param list A set object to which names of data attributes are added as String objects. */ ! public void buildRequiredDataAttributesSet(Set list) { ! datasource.buildRequiredDataAttributesSet(list); } --- 258,267 ---- } ! /** Build metatdata * ! * @param descriptor Object to accumulate metadata */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor) { ! datasource.buildRecordWriterDescriptor(descriptor); } *************** *** 335,349 **** * static value. Otherwise returns null. * ! * @return Static data value, or null */ ! public Object getValue() { ! if (datasource instanceof StaticDataSource) { ! return ((StaticDataSource)datasource).getValue(); ! } else { ! return null; ! } ! ! } ! /** Get the name of the record attribute written by this writer. * --- 279,293 ---- * static value. Otherwise returns null. * ! * @return Static data value, or null */ ! public Object getValue() { ! if (datasource instanceof StaticDataSource) { ! return ((StaticDataSource)datasource).getValue(); ! } else { ! return null; ! } ! ! } ! /** Get the name of the record attribute written by this writer. * *************** *** 351,364 **** * of that record attribute. Otherwise returns null. * ! * @return attribute name, or null */ ! public String getAttributeName() { ! if (datasource instanceof AttributeDataSource) { ! return ((AttributeDataSource)datasource).getAttributeName(); ! } else { ! return null; ! } ! } ! /** Get the type of the record attribute written by this writer. * --- 295,308 ---- * of that record attribute. Otherwise returns null. * ! * @return attribute name, or null */ ! public String getAttributeName() { ! if (datasource instanceof AttributeDataSource) { ! return ((AttributeDataSource)datasource).getAttributeName(); ! } else { ! return null; ! } ! } ! /** Get the type of the record attribute written by this writer. * *************** *** 366,405 **** * of that record attribute. Otherwise undefined. * ! * @return attribute type (undefined if no attribute type) */ ! public int getAttributeType() { ! if (datasource instanceof AttributeDataSource) { ! return ((AttributeDataSource)datasource).getAttributeType(); ! } else { ! return -1; ! } ! } ! ! /** Get any format applied to data before output. ! * ! * @return A format (if any) applied to data before output. ! */ ! public Format getFormat() { ! return format; ! } ! ! /** Equality operator. ! * ! * @param other Object to test for equality with this. ! * @return true if other is a GenericElementWriter with equal datasource and format. ! */ ! public boolean equals(Object other) { ! if (other instanceof GenericElementWriter) { ! GenericElementWriter other_wr = (GenericElementWriter)other; ! if (this.datasource.equals(other_wr.datasource)) { ! if (this.format == null || other_wr.format == null) { ! return this.format == other_wr.format; ! } else { ! return this.format.equals(other_wr.format); ! } ! } ! } ! return false; ! } } --- 310,349 ---- * of that record attribute. Otherwise undefined. * ! * @return attribute type (undefined if no attribute type) */ ! public int getAttributeType() { ! if (datasource instanceof AttributeDataSource) { ! return ((AttributeDataSource)datasource).getAttributeType(); ! } else { ! return -1; ! } ! } ! ! /** Get any format applied to data before output. ! * ! * @return A format (if any) applied to data before output. ! */ ! public Format getFormat() { ! return format; ! } ! ! /** Equality operator. ! * ! * @param other Object to test for equality with this. ! * @return true if other is a GenericElementWriter with equal datasource and format. ! */ ! public boolean equals(Object other) { ! if (other instanceof GenericElementWriter) { ! GenericElementWriter other_wr = (GenericElementWriter)other; ! if (this.datasource.equals(other_wr.datasource)) { ! if (this.format == null || other_wr.format == null) { ! return this.format == other_wr.format; ! } else { ! return this.format.equals(other_wr.format); ! } ! } ! } ! return false; ! } } Index: GenericFieldWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericFieldWriter.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** GenericFieldWriter.java 21 Jun 2004 10:13:37 -0000 1.7 --- GenericFieldWriter.java 14 Jul 2004 16:05:44 -0000 1.8 *************** *** 35,39 **** * @author Jonathan Essex */ ! public class GenericFieldWriter extends GenericElementWriter implements RecordElementWriter { private String class_id; --- 35,39 ---- * @author Jonathan Essex */ ! public class GenericFieldWriter extends GenericElementWriter implements FieldWriter { private String class_id; Index: GenericGridAttributesWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericGridAttributesWriter.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** GenericGridAttributesWriter.java 22 Jun 2004 08:23:32 -0000 1.4 --- GenericGridAttributesWriter.java 14 Jul 2004 16:05:44 -0000 1.5 *************** *** 14,17 **** --- 14,22 ---- import org.jdaemon.util.AttributeList; + import java.util.Arrays; + import java.util.List; + import java.util.ArrayList; + import java.util.Iterator; + /** Write a grid attributes element to a report builder. * <P> *************** *** 45,52 **** * @author Jonathan Essex */ ! public class GenericGridAttributesWriter extends GenericElementCollectionWriter implements GridAttributesWriter { private String class_id; ! /** Creates a new instance of GenericGridAttributesWriter * --- 50,58 ---- * @author Jonathan Essex */ ! public class GenericGridAttributesWriter implements GridAttributesWriter { private String class_id; ! private List cell_attrs; ! /** Creates a new instance of GenericGridAttributesWriter * *************** *** 54,79 **** */ public GenericGridAttributesWriter(String class_id, CellAttributesWriter[] cell_attrs) { - super(cell_attrs); this.class_id = class_id; } ! ! /** Send end element event to builder. ! * ! * @param builder ReportBuilder to send start element event to ! * ! */ ! protected void endElement(ReportBuilder builder) throws BuildException { ! builder.endGridAttributes(); ! } ! ! /** Send start element event to builder. ! * ! * @param builder ReportBuilder to send end element event to ! * ! */ ! protected void startElement(ReportBuilder builder) throws BuildException { ! builder.startGridAttributes(class_id, AttributeList.EMPTY); ! } ! /** Get value of class attribute. * --- 60,67 ---- */ public GenericGridAttributesWriter(String class_id, CellAttributesWriter[] cell_attrs) { this.class_id = class_id; + this.cell_attrs = new ArrayList(Arrays.asList(cell_attrs)); } ! /** Get value of class attribute. * *************** *** 96,103 **** GenericGridAttributesWriter other_wr = (GenericGridAttributesWriter)other; if (this.class_id == null || other_wr.class_id == null) { ! return this.class_id == other_wr.class_id && this.listElements().equals(other_wr.listElements()); } else { ! return this.class_id.equals(other_wr.class_id) && this.listElements().equals(other_wr.listElements()); } } } --- 84,121 ---- GenericGridAttributesWriter other_wr = (GenericGridAttributesWriter)other; if (this.class_id == null || other_wr.class_id == null) { ! return this.class_id == other_wr.class_id && this.cell_attrs.equals(other_wr.cell_attrs); } else { ! return this.class_id.equals(other_wr.class_id) && this.cell_attrs.equals(other_wr.cell_attrs); } } + + + /** Hash function. + * + * @return the hash code of the class id + */ + public int hashCode() { + return class_id.hashCode(); + } + + /** Output Grid Attributes to builder. + * + * @param builder to output grid attributes to + * @throws BuildException on any error in output + */ + public void write(ReportBuilder builder) throws BuildException { + builder.startGridAttributes(class_id, AttributeList.EMPTY); + Iterator i = cell_attrs.iterator(); + while (i.hasNext()) ((CellAttributesWriter)i.next()).write(builder); + builder.endGridAttributes(); + } + + /** Add an element to the grid attributes block + * + * @param element Element to add + */ + public void addElement(CellAttributesWriter element) { + cell_attrs.add(element); + } + } Index: GenericGridWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericGridWriter.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** GenericGridWriter.java 22 Jun 2004 08:23:32 -0000 1.5 --- GenericGridWriter.java 14 Jul 2004 16:05:44 -0000 1.6 *************** *** 14,17 **** --- 14,19 ---- import org.jdaemon.util.AttributeList; + import java.util.Iterator; + /** Generic implemntation of class to write a grid element out to a builder. * <P> *************** *** 38,41 **** --- 40,44 ---- private String class_id; + private GridAttributesWriter attrs; /** Creates a new instance of GenericGridWriter. *************** *** 53,56 **** --- 56,64 ---- super(elements); this.class_id = class_id; + + CellAttributesWriter[] cell_attrs = new CellAttributesWriter [elements.length]; + for (int i = 0; i < cell_attrs.length; i++) cell_attrs[i] = elements[i].getCellAttributesWriter(); + + this.attrs = new GenericGridAttributesWriter(class_id, cell_attrs); } *************** *** 78,81 **** --- 86,90 ---- public void addElement(CellWriter cell_writer) { super.addElement(cell_writer); + attrs.addElement(cell_writer.getCellAttributesWriter()); } *************** *** 119,122 **** return this.class_id.equals(other_wr.class_id) && this.listElements().equals(other_wr.listElements()); } ! } } --- 128,144 ---- return this.class_id.equals(other_wr.class_id) && this.listElements().equals(other_wr.listElements()); } ! } ! ! /** Register this grid writer in RecordWriterDescriptor ! */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor desc) { ! super.buildRecordWriterDescriptor(desc); ! desc.registerGridAttributesWriter(getGridAttributesWriter()); ! } ! ! /** Get a grid attributes writer describing this grid block. ! */ ! public GridAttributesWriter getGridAttributesWriter() { ! return attrs; ! } } Index: GenericRecordWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericRecordWriter.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** GenericRecordWriter.java 21 Jun 2004 16:43:26 -0000 1.6 --- GenericRecordWriter.java 14 Jul 2004 16:05:44 -0000 1.7 *************** *** 60,63 **** --- 60,83 ---- private String class_id; + /** Metadata concenring this RecordWriter + */ + private RecordWriterDescriptor descriptor; + + /** get metadata concerning this RecordWriter + * + * @return A RecordWriterDescriptor containing info about this RecordWriter + */ + public RecordWriterDescriptor getDescriptor() { + + // So if the element list ever changes we just have to set + // descriptor to null and it will be recreated on demand. + if (descriptor == null) { + descriptor = new RecordWriterDescriptor(); + buildRecordWriterDescriptor(descriptor); + } + + return descriptor; + } + /** Creates a new instance of GenericRecordWriter. * <P> *************** *** 75,78 **** --- 95,99 ---- super(elements); this.class_id = class_id; + this.descriptor = null; } *************** *** 103,106 **** --- 124,128 ---- public void addElement(RecordElementWriter field_writer) { super.addElement(field_writer); + this.descriptor = null; } *************** *** 136,148 **** return null; } ! ! /** Get a list of the Aggregate data required by this formatting. * ! * @return a List of Aggregate objects describing the data required by this formatting */ ! public List getRequiredAggregates() { ! HashSet set = new HashSet(); ! buildRequiredAggregatesSet(set); ! return Arrays.asList(set.toArray()); } --- 158,168 ---- return null; } ! ! /** Get a list of the base data required by this formatting. * ! * @return a List of String objects containing the names of the base data fields required by this formatting. */ ! public List getRequiredDataAttributes() { ! return Arrays.asList(getDescriptor().getRequiredDataAttributes().toArray()); } *************** *** 151,160 **** * @return a List of String objects containing the names of the base data fields required by this formatting. */ ! public List getRequiredDataAttributes() { ! HashSet set = new HashSet(); ! buildRequiredDataAttributesSet(set); ! return Arrays.asList(set.toArray()); } ! /** Get the value of the class attribute for records written by this writer. * --- 171,178 ---- * @return a List of String objects containing the names of the base data fields required by this formatting. */ ! public List getRequiredAggregates() { ! return Arrays.asList(getDescriptor().getRequiredAggregates().toArray()); } ! /** Get the value of the class attribute for records written by this writer. * *************** *** 177,179 **** --- 195,202 ---- } } + + public void registerHeaderElements(HeaderWriter headerwriter) { + getDescriptor().registerHeaderElements(headerwriter); + } + } Index: GenericRecordsetWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GenericRecordsetWriter.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** GenericRecordsetWriter.java 21 Jun 2004 16:43:26 -0000 1.7 --- GenericRecordsetWriter.java 14 Jul 2004 16:05:44 -0000 1.8 *************** *** 99,102 **** return this.class_id.equals(other_wr.class_id); } ! } } --- 99,116 ---- return this.class_id.equals(other_wr.class_id); } ! } ! ! /** Build descriptor for record writer. ! * ! * Does nothing here, as a recordset element is where we drop down to the next ! * level record writer - hence nothing inside a recordset element is relavent ! * to describin the record writer at the current level. ! * ! * Actually this whole 'RecordWriterDescriptor' thing sucks and I'll look at ! * tidying it up. ! * ! * @param descriptor unused ! */ ! public void buildRecordWriterDescriptor(RecordWriterDescriptor descriptor) { ! } } Index: GridAttributesWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/GridAttributesWriter.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** GridAttributesWriter.java 20 Jun 2004 19:56:26 -0000 1.4 --- GridAttributesWriter.java 14 Jul 2004 16:05:44 -0000 1.5 *************** *** 10,13 **** --- 10,16 ---- package org.jdaemon.era.grml; + import org.jdaemon.six.ReportBuilder; + import org.jdaemon.six.BuildException; + /** Interface for writing grid-attributes elements to a writer. * <P> *************** *** 31,35 **** * @author Jonathan Essex */ ! public interface GridAttributesWriter extends ElementWriter { /** Get value of class attribute. --- 34,38 ---- * @author Jonathan Essex */ ! public interface GridAttributesWriter { /** Get value of class attribute. *************** *** 43,45 **** --- 46,60 ---- public String getClassAttribute(); + /** Write grid attributes to builder + * + * @param builder Builder to output grid attributes element to + * @throws BuildException on any error in processing ouptut. + */ + public void write(ReportBuilder builder) throws BuildException; + + /** Add an element to the grid attributes block + * + * @param element Element to add + */ + public void addElement(CellAttributesWriter element); } Index: RecordWriter.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/RecordWriter.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** RecordWriter.java 13 Jun 2004 21:05:19 -0000 1.4 --- RecordWriter.java 14 Jul 2004 16:05:44 -0000 1.5 *************** *** 32,35 **** */ public void write( Record record, ! ReportBuilder builder ) throws BuildException; } --- 32,37 ---- */ public void write( Record record, ! ReportBuilder builder ) throws BuildException; ! ! public void registerHeaderElements(HeaderWriter headerwriter); } Index: TestGRMLReport.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/era/grml/TestGRMLReport.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** TestGRMLReport.java 22 Jun 2004 08:23:32 -0000 1.12 --- TestGRMLReport.java 14 Jul 2004 16:05:44 -0000 1.13 *************** *** 10,13 **** --- 10,14 ---- import org.jdaemon.era.*; import org.jdaemon.era.helper.GroupingImpl; + import org.jdaemon.era.helper.HelperTypes; import org.jdaemon.six.*; import org.jdaemon.test.era.TestData; *************** *** 28,31 **** --- 29,33 ---- import javax.xml.transform.TransformerException; + /** Test cases for GRMLReport and related classes * *... [truncated message content] |
|
From: <je...@us...> - 2004-07-13 10:11:24
|
Update of /cvsroot/era/src/org/jdaemon/six In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7389 Added Files: AbstractBuilder.java Log Message: Abstract builder. Bit of a dead end for now. But interesting enough to keep it around. --- NEW FILE: AbstractBuilder.java --- /* * AbstractBuilder.java * * Created on July 12, 2004, 4:01 PM */ package org.jdaemon.six; import org.jdaemon.util.AttributeList; import java.util.Stack; import java.util.List; import java.util.ArrayList; import java.util.Collections; /** Abstract class for use as base for Builder implementations. * <P> * Lightweight base implemntation for builders that create custom object trees. Unbalanced * calls to startElement and endElement will generate an exception when endElement is * called. * </P><P> * Implement the getNamespace method and the consume method. * </P><P> * The consume method will get called once for each endElement call. Any object returned * by the consume method will be added to the content array passed to consume method when * the parent element's endElement is encountered. * </P> * <B>Note - as of this time, this class is completely untested</B> * @author Jonathan Essex. */ public abstract class AbstractBuilder implements Builder { private ArrayList objects; private Stack state; private Element current; private int ix_end; private Namespace default_ns; /** Inner class for entry in state stack */ public static class Element { private ElementType type; private AttributeList attributes; private int ix_start; public Element(ElementType type, AttributeList attributes, int ix_start) { this.type = type; this.attributes = attributes; this.ix_start = ix_start; } public ElementType getElementType() { return type; } public AttributeList getAttributeList() { return attributes; } } /** Provide read-only access to state. * * @return read-only list of the parents of the current element. */ public List getState() { return Collections.unmodifiableList(state); } /** Creates a new instance of AbstractBuilder. * * Note: the startElement(String, AttributeList) and endElement(String) methods * will not work properly until a default namespace is set. */ public AbstractBuilder() { objects = new ArrayList(); state = new Stack(); current = null; ix_end = 0; } /** End an element. * * Equivalent to endElement(getDefaultNamespace().getElementType(type)) * * @param type Name of the element type in the default namespace */ public void endElement(String type) throws BuildException { endElement(getDefaultNamespace().getElementType(type)); } /** End an element. * * Indicate to builder that the current element is complete. Will result in a call * to the consume method with parameters giving the type, attributes, and content * of the current element. * * @param type Type of the element to complete. */ public void endElement(ElementType type) throws BuildException { // -FIXME- make BuildException more descriptive if (current == null) throw new BuildException("Unbalanced element close"); if (!current.type.equals(type)) throw new BuildException("Wrong type"); if (state.isEmpty()) { current = null; } Object result = consume(current.type, current.attributes, objects.subList(current.ix_start, ix_end)); ix_end = current.ix_start; current = (Element)state.pop(); if (result != null) writeObject(result); } /** Process a completed element. * <P> * This is the interesting part. Any obejct returned by consume() will be added to the * content list passed to the consume method of it's parent element. So in this way we * can simply decide to keep around data or not... * </P> * @param type Type of element to process * @param attribtes Attributes of element to process * @param content Content of element to process */ public abstract Object consume(ElementType type, AttributeList attributes, List content); /** Get the current default namespace. * * The startElement(String, AttributeList) and endElemnt(String) methods use the current * default namespace to convert the given string into an element type. * * @return the current default namespace. */ public Namespace getDefaultNamespace() { return default_ns; } /** Get a namespace with the given attributes. * * @param attributes Implementation-depended way to specify a namespace. * @return a Namespace */ public abstract Namespace getNamespace(org.jdaemon.util.AttributeList attributes); /** Set the current default namespace. * * The startElement(String, AttributeList) and endElemnt(String) methods use the current * default namespace to convert the given string into an element type. * * @param namespace a new default namespace. */ public void setDefaultNamespace(Namespace namespace) { default_ns = namespace; } /** Start an element. * * Equivalent to startElement(getDefaultNamespace().getElementType(type), attributes) * * @param type Name of the element type in the default namespace * @param attributes Attributes of this element */ public void startElement(String type, org.jdaemon.util.AttributeList attributes) throws BuildException { startElement(getDefaultNamespace().getElementType(type), attributes); } /** End an element. * * Indicate to builder that a new element is started. This becomes the current element * until a matching endElement call. * * @param type Type of the element to start. * @param attributes Attributes of this element */ public void startElement(ElementType type, org.jdaemon.util.AttributeList attributes) throws BuildException { if (current != null) { state.push(current); } current = new Element(type, attributes, ix_end); } /** Add content to an element * * @param content Object contained by element */ public void writeObject(Object content) throws BuildException { objects.add(ix_end, content); ix_end++; } } |
Update of /cvsroot/era/src/org/jdaemon/util/data In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14794 Modified Files: DataRepresentation.java ListType.java Types.java Added Files: MapEntryType.java MapType.java StringMapType.java Log Message: Map types - untested as yet --- NEW FILE: MapEntryType.java --- /* * ArrayType.java * * Copyright (C) 2002 Jonathan Essex * This program is distributed under the terms of the Lesser GNU General Public * License (v2 or later) per the included COPYING.txt file, or see www.fsf.org. * * Created on September 21, 2002, 2:35 PM */ package org.jdaemon.util.data; import java.util.Iterator; import java.util.TreeMap; import java.util.Map; /** Type object for Saving/Loading map entry objects from a DataRepresentation. * * @author Jonathan Essex */ class MapEntryType extends Type { private Type value_type; private Type key_type; /** Quick and dirty map entry implementation. */ private class MyMapEntry implements Map.Entry { /** Key attribute */ private final Object key; /** Value attribute */ private Object value; /** Get key attribute. * * @return value of key attribute */ public Object getKey() { return key; } /** Get value attribute. * * @return the value of the value attribute (!) */ public Object getValue() { return value; } /** Set the value attribute. * * @param obj new value for value attribute * @return old value of the value attribute */ public Object setValue(Object obj) { Object old = value; value = obj; return old; } /** Construct a new map entry. * * @param key value for key attribute * @param value value for value attribute */ public MyMapEntry(Object key, Object value) { this.key = key; this.value = value; } }; /** Creates a new instance of MapEntryType */ public MapEntryType(Type value_type, Type key_type) { super ("Entry", Map.Entry.class); this.value_type = value_type; this.key_type = key_type; } /** Reads a map entry from some DataRepresentation. * * @param representation Data representation from which we will read attributes and elements to create a new map entry * @throws ReadError Thrown when data cannot be read from <I>representation</I> * @throws ObjectInstantiationError Thrown when there is a problem creating a new instance of the required class * @return A new map entry containing key and value of the type given in the constructor of this object */ public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { return new MyMapEntry(key_type.get(representation, "key"), value_type.get(representation, "value")); } /** Writes a map entry to some DataRepresentation. * * @param representation Data representation to which we will write a new map entry * @param object map entry to be written to <I>representation</I> * @throws WriteError Thrown when data cannot be written to <I>representation</I> */ public void write(DataRepresentation representation, Object object) throws WriteError { key_type.put(representation, "key", ((Map.Entry)object).getKey()); value_type.put(representation, "value", ((Map.Entry)object).getValue()); } } --- NEW FILE: MapType.java --- /* * ArrayType.java * * Copyright (C) 2002 Jonathan Essex * This program is distributed under the terms of the Lesser GNU General Public * License (v2 or later) per the included COPYING.txt file, or see www.fsf.org. * * Created on September 21, 2002, 2:35 PM */ package org.jdaemon.util.data; import java.util.Iterator; import java.util.TreeMap; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; /** Type object for Saving/Loading maps from a DataRepresentation * * @author Jonathan Essex */ class MapType extends Type { private Type entry_type; /** Creates a new instance of MapType. * * @param key_type Type for key objects * @param value_type Type for value objects */ public MapType(Type key_type, Type element_type) { super ("Map", Map.class); this.entry_type = new MapEntryType(key_type, element_type); } /** Reads a map of objects from some DataRepresentation. * * @param representation Data representation from which we will read attributes and elements to create a new map * @throws ReadError Thrown when data cannot be read from <I>representation</I> * @throws ObjectInstantiationError Thrown when there is a problem creating a new instance of the required class * @return A new map containing key/value pairs of the type given in the constructor of this object */ public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { Iterator elements = representation.getElementKeys(); TreeMap map = new TreeMap(); while (elements.hasNext()) { Object key = elements.next(); Map.Entry elem = (Map.Entry)entry_type.get(representation, key); map.put(elem.getKey(), elem.getValue()); } return map; } /** Writes a map of objects to some DataRepresentation. * * @param representation Data representation to which we will write elements of the given map to create a new element * @param object array to be written to <I>representation</I> * @throws WriteError Thrown when data cannot be written to <I>representation</I> */ public void write(DataRepresentation representation, Object object) throws WriteError { Iterator i = ((Map)object).entrySet().iterator(); int count = 0; while (i.hasNext()) { entry_type.put(representation, new Integer(count), i.next()); count++; } } } --- NEW FILE: StringMapType.java --- /* * ArrayType.java * * Copyright (C) 2002 Jonathan Essex * This program is distributed under the terms of the Lesser GNU General Public * License (v2 or later) per the included COPYING.txt file, or see www.fsf.org. * * Created on September 21, 2002, 2:35 PM */ package org.jdaemon.util.data; import java.util.Iterator; import java.util.TreeMap; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; /** Type object for Saving/Loading maps from a DataRepresentation. * * This class deals with the special case where the map key is a string. Otherwise use MapType. * * @author Jonathan Essex */ class StringMapType extends Type { private Type value_type; /** Creates a new instance of StringMapType. * * @param value_type type of value contained by map (key is always a string). */ public StringMapType(Type value_type) { super ("StringMap", Map.class); this.value_type = value_type; } /** Reads a map of objects from some DataRepresentation. * * @param representation Data representation from which we will read attributes and elements to create a new map * @throws ReadError Thrown when data cannot be read from <I>representation</I> * @throws ObjectInstantiationError Thrown when there is a problem creating a new instance of the required class * @return A new map containing key/value pairs of the type given in the constructor of this object */ public Object read(DataRepresentation representation) throws ReadError, ObjectInstantiationError { Iterator elements = representation.getElementKeys(); TreeMap map = new TreeMap(); while (elements.hasNext()) { Object key = elements.next(); Object value = value_type.get(representation, key); map.put(key, value); } return map; } /** Writes a map of objects to some DataRepresentation. * * @param representation Data representation to which we will write elements of the given map to create a new element * @param object array to be written to <I>representation</I> * @throws WriteError Thrown when data cannot be written to <I>representation</I> */ public void write(DataRepresentation representation, Object object) throws WriteError { Iterator i = ((Map)object).entrySet().iterator(); while (i.hasNext()) { Map.Entry entry = (Map.Entry)i.next(); value_type.put(representation, entry.getKey(), entry.getValue()); } } } Index: DataRepresentation.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/data/DataRepresentation.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** DataRepresentation.java 24 Dec 2002 15:36:57 -0000 1.6 --- DataRepresentation.java 7 Jul 2004 14:41:29 -0000 1.7 *************** *** 33,37 **** * from attributes of the directory, and Elements are derived from sub-directories. * </P> ! * @author jonathan * @version */ --- 33,38 ---- * from attributes of the directory, and Elements are derived from sub-directories. * </P> ! * ! * @author Jonathan Essex * @version */ Index: ListType.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/data/ListType.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ListType.java 21 Jun 2004 15:15:20 -0000 1.1 --- ListType.java 7 Jul 2004 14:41:29 -0000 1.2 *************** *** 16,20 **** import java.util.ArrayList; ! /** Type object for Saving/Loading arrays from a DataRepresentation * * @author Jonathan Essex --- 16,20 ---- import java.util.ArrayList; ! /** Type object for Saving/Loading lists from a DataRepresentation. * * @author Jonathan Essex Index: Types.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/data/Types.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Types.java 23 Jun 2004 12:30:39 -0000 1.5 --- Types.java 7 Jul 2004 14:41:29 -0000 1.6 *************** *** 43,45 **** --- 43,65 ---- return new ListType(element_type); } + + /** Get a Type object for a map with keys and values of the types. + * + * @param key_type Type object for map keys + * @param value_type Type object for map values + * @return A type object representing a Map with the given key and value types + */ + public static Type mapOf(Type key_type, Type value_type) { + return new MapType(key_type, value_type); + } + + /** Get a Type object for a map of Strings to values of the given type + * + * @param value_type Type object for values in the map + * @return A Type object representing a map of strings to values of the given type + */ + public static Type mapOf(Type value_type) { + return new StringMapType(value_type); + } + } |