Permalink
Browse files

[core] Refactor RowList with self-type trick on append/labeling opera…

…tion.

```java
// Before this change
RowList1<String> l1 = new RowList1<String>(String.class);
RowList<Row1<A>> l1updated = l1.append("str");
// Self-type RowList1<A> of l1 is lost in append operation

// Now
RowList1.Impl<String> l2 = new RowList1.Impl<String>(String.class);
RowList1.Impl<String> l2updated = l2.append("str");
// Implementation self-type is kept
```
  • Loading branch information...
cchantep
cchantep committed Jan 8, 2014
1 parent a447ac9 commit b4d944aaee23afbeeb8aa09cd97c3741c83f7fd8
@@ -1,135 +0,0 @@
package acolyte;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import acolyte.Row.Row1;
/**
* Row list of row with 1 cell.
*
* @author Cedric Chantepie
*/
public final class RowList1<A> extends RowList<Row1<A>> {
// --- Properties ---
/**
* Rows
*/
private final List<Row1<A>> rows;
/**
* Column names
*/
private final Map<String,Integer> colNames;
/**
* Class of column #1
*/
private final Class<A> c1;
/**
* Column classes
*/
private final ArrayList<Class<?>> colClasses;
// --- Constructors ---
/**
* Bulk constructor.
*
* @throws IllegalArgumentException if rows is null
*/
protected RowList1(final Class<A> c1,
final List<Row1<A>> rows,
final Map<String,Integer> colNames) {
if (c1 == null) {
throw new IllegalArgumentException("Invalid class for column #1");
} // end of if
if (rows == null) {
throw new IllegalArgumentException("Invalid rows");
} // end of if
if (colNames == null) {
throw new IllegalArgumentException("Invalid names");
} // end of if
this.rows = Collections.unmodifiableList(rows);
this.colNames = Collections.unmodifiableMap(colNames);
// Column classes
final ArrayList<Class<?>> colClasses = new ArrayList<Class<?>>();
this.c1 = c1;
colClasses.add(c1);
this.colClasses = colClasses;
} // end of <init>
/**
* No-arg constructor.
*/
public RowList1(final Class<A> c1) {
this(c1, new ArrayList<Row1<A>>(), new HashMap<String,Integer>());
} // end of <init>
// ---
/**
* {@inheritDoc}
*/
public List<Row1<A>> getRows() { return this.rows; }
/**
* {@inheritDoc}
*/
public Map<String,Integer> getColumnLabels() { return this.colNames; }
/**
* Convinience append.
*/
public RowList1<A> append(final A value) {
return append(new Row1<A>(value));
} // end of append
/**
* {@inheritDoc}
*/
public RowList1<A> append(final Row1<A> row) {
final ArrayList<Row1<A>> copy = new ArrayList<Row1<A>>(this.rows);
copy.add(row);
return new RowList1<A>(this.c1, copy, this.colNames);
} // end of append
/**
* {@inheritDoc}
*/
public RowList1<A> withLabel(final int columnIndex, final String label) {
if (label == null) {
throw new IllegalArgumentException("Invalid label");
} // end of if
// ---
final HashMap<String,Integer> cols =
new HashMap<String,Integer>(this.colNames);
cols.put(label, (Integer) columnIndex);
return new RowList1<A>(this.c1, this.rows, cols);
} // end of withLabel
/**
* {@inheritDoc}
*/
public List<Class<?>> getColumnClasses() {
return this.colClasses;
} // end of getColumnClasses
} // end of class RowList1
@@ -21,7 +21,7 @@ public final class Row#N#<#CP#> implements Row {
/**
* Copy constructor.
*/
public Row#N#(#IP#) {
Row#N#(#IP#) {
#AS#
final ArrayList<Object> cs = new ArrayList<Object>();
@@ -34,7 +34,7 @@ public final class Row#N#<#CP#> implements Row {
/**
* No arg constructor, with null cells.
*/
public Row#N#() {
Row#N#() {
this(#NA#);
} // end of <init>
@@ -8,122 +8,158 @@ import java.util.List;
import java.util.Map;
/**
* Row list of row with #N# cells.
* Row list of row with #N# cell.
*
* @author Cedric Chantepie
*/
public final class RowList#N#<#CP#> extends RowList<Row#N#<#CP#>> {
// --- Properties ---
public abstract class RowList#N#<#CP#,UPDATED extends RowList#N#<#CP#,?>>
extends RowList<Row#N#<#CP#>> {
#AGS#
/**
* Rows
* Returns row list factory.
*/
private final List<Row#N#<#CP#>> rows;
abstract Factory<#CP#, UPDATED> factory();
/**
* Column names
* Append column values.
* see #append(acolyte#Row#N#)
*/
private final Map<String,Integer> colNames;
#PS#
public UPDATED append(#AP#) {
return append(new Row#N#<#CP#>(#AV#));
} // end of append
/**
* Column classes
* {@inheritDoc}
*/
private final ArrayList<Class<?>> colClasses;
public UPDATED append(final Row#N#<#CP#> row) {
final ArrayList<Row#N#<#CP#>> copy = new ArrayList<Row#N#<#CP#>>(getRows());
copy.add(row);
// --- Constructors ---
return factory().rowList(#GC#, copy, getColumnLabels());
} // end of append
/**
* Bulk constructor.
*
* @throws IllegalArgumentException if rows is null
* {@inheritDoc}
*/
protected RowList#N#(#CS#, final List<Row#N#<#CP#>> rows, final Map<String,Integer> colNames) {
#IC#
if (rows == null) {
throw new IllegalArgumentException("Invalid rows");
public UPDATED withLabel(final int columnIndex, final String label) {
if (label == null) {
throw new IllegalArgumentException("Invalid label");
} // end of if
if (colNames == null) {
throw new IllegalArgumentException("Invalid names");
} // end of if
// ---
this.rows = Collections.unmodifiableList(rows);
this.colNames = Collections.unmodifiableMap(colNames);
final HashMap<String,Integer> cols =
new HashMap<String,Integer>(getColumnLabels());
// Column classes
final ArrayList<Class<?>> colClasses = new ArrayList<Class<?>>();
cols.put(label, (Integer) columnIndex);
#AC#
return factory().rowList(#GC#, getRows(), cols);
} // end of withLabel
this.colClasses = colClasses;
} // end of <init>
// --- Inner classes ---
/**
* No-arg constructor.
* Row list factory.
*/
public RowList#N#(#CS#) {
this(#CA#, new ArrayList<Row#N#<#CP#>>(), new HashMap<String,Integer>());
} // end of <init>
static interface Factory<#CP#, ROWLIST extends RowList#N#<#CP#,?>> {
// ---
/**
* Build row list, including |rows| with given column |labels|.
*/
public ROWLIST rowList(#CS#, final List<Row#N#<#CP#>> rows, final Map<String,Integer> labels);
} // end of interface Factory
/**
* {@inheritDoc}
* Row list implementation.
*/
public List<Row#N#<#CP#>> getRows() { return this.rows; }
public static final class Impl<#CP#> extends RowList#N#<#CP#,Impl<#CP#>> {
// --- Properties ---
/**
* Rows
*/
final List<Row#N#<#CP#>> rows;
/**
* Column names
*/
final Map<String,Integer> colNames;
/**
* {@inheritDoc}
*/
public Map<String,Integer> getColumnLabels() { return this.colNames; }
#PS#
/**
* Appends row with with given values.
*
* @see #append(acolyte.Row)
*/
public RowList#N#<#CP#> append(#AP#) {
return append(new Row#N#<#CP#>(#AV#));
} // end of append
/**
* Column classes
*/
private final List<Class<?>> colClasses;
/**
* {@inheritDoc}
*/
public RowList#N#<#CP#> append(final Row#N#<#CP#> row) {
final ArrayList<Row#N#<#CP#>> copy = new ArrayList<Row#N#<#CP#>>(this.rows);
copy.add(row);
return new RowList#N#<#CP#>(#CA#, copy, this.colNames);
} // end of append
// --- Constructors ---
/**
* {@inheritDoc}
*/
public RowList#N#<#CP#> withLabel(final int columnIndex, final String label) {
/**
* Bulk constructor.
*
* @throws IllegalArgumentException if rows is null
*/
Impl(#CS#, final List<Row#N#<#CP#>> rows, final Map<String,Integer> colNames) {
if (label == null) {
throw new IllegalArgumentException("Invalid label");
} // end of if
#IC#
// ---
if (rows == null) {
throw new IllegalArgumentException("Invalid rows");
} // end of if
final HashMap<String,Integer> cols =
new HashMap<String,Integer>(this.colNames);
if (colNames == null) {
throw new IllegalArgumentException("Invalid names");
} // end of if
cols.put(label, (Integer) columnIndex);
this.rows = Collections.unmodifiableList(rows);
this.colNames = Collections.unmodifiableMap(colNames);
return new RowList#N#<#CP#>(#CA#, this.rows, cols);
} // end of withLabel
// Column classes
final ArrayList<Class<?>> colClasses = new ArrayList<Class<?>>();
#AC#
this.colClasses = Collections.unmodifiableList(colClasses);
} // end of <init>
/**
* No-arg constructor.
*/
Impl(#CS#) {
this(#CA#, new ArrayList<Row#N#<#CP#>>(), new HashMap<String,Integer>());
} // end of <init>
// ---
#GS#
/**
* {@inheritDoc}
*/
RowList#N#.Factory<#CP#, Impl<#CP#>> factory() {
return new RowList#N#.Factory<#CP#,Impl<#CP#>>() {
public Impl<#CP#> rowList(#CS#, final List<Row#N#<#CP#>> rows, final Map<String,Integer> colNames) {
return new Impl(#PSC#, rows, colNames);
}
};
} // end of factory
/**
* {@inheritDoc}
*/
public List<Row#N#<#CP#>> getRows() { return this.rows; }
/**
* {@inheritDoc}
*/
public List<Class<?>> getColumnClasses() {
return this.colClasses;
} // end of getColumnClasses
/**
* {@inheritDoc}
*/
public Map<String,Integer> getColumnLabels() { return this.colNames; }
/**
* {@inheritDoc}
*/
public List<Class<?>> getColumnClasses() { return this.colClasses; }
} // end of class Impl
} // end of class RowList#N#
Oops, something went wrong.

0 comments on commit b4d944a

Please sign in to comment.