/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt
******************************************************************************/
package com.opendoorlogistics.core.tables.memory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import com.opendoorlogistics.api.tables.ODLColumnType;
import com.opendoorlogistics.api.tables.ODLTableDefinitionAlterable;
import com.opendoorlogistics.core.tables.utils.TableUtils;
import com.opendoorlogistics.core.utils.IntIDGenerator;
import com.opendoorlogistics.core.utils.IntIDGenerator.IsExistingId;
import com.opendoorlogistics.core.utils.strings.Strings;
import com.opendoorlogistics.core.utils.JAXBUtils;
@XmlRootElement(name = "Table")
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class ODLAbstractTableDefinition<T extends ODLColumnDefinition> extends ODLHasFlags implements ODLTableDefinitionAlterable, Serializable{
/**
*
*/
private static final long serialVersionUID = -5898189091620297143L;
@XmlTransient
private final IntIDGenerator columnIdGenerator = new IntIDGenerator(new IsExistingId() {
@Override
public boolean isExistingId(int id) {
for(ODLColumnDefinition col:columns){
if(id==col.getImmutableId()){
return true;
}
}
return false;
}
});
//@XmlElement(name = "Column")
@XmlTransient
protected List<T> columns = new ArrayList<>();
@XmlTransient
private final int id;
@XmlAttribute
private String name;
@XmlTransient
private Set<String> tags = new TreeSet<>();
public ODLAbstractTableDefinition(int id, String name){
this.name = name;
this.id = id;
}
/**
* No-args constructor used by JAXB but nothing else
*/
public ODLAbstractTableDefinition(){
id=-1;
}
public ODLAbstractTableDefinition(ODLAbstractTableDefinition<T> copyThis){
super(copyThis);
this.id = copyThis.getImmutableId();
this.name = copyThis.getName();
for(T col : copyThis.columns){
columns.add((T)col.deepCopy());
}
this.tags.addAll(copyThis.getTags());
this.columnIdGenerator.setNextId(copyThis.columnIdGenerator.getNextId());
}
@Override
public synchronized ODLColumnType getColumnType(int i) {
if(i<columns.size()){
return columns.get(i).getType();
}
return null;
}
@Override
public synchronized String getColumnName(int i) {
if(i>=columns.size()){
return null;
}
return columns.get(i).getName();
}
@Override
public synchronized int getColumnCount() {
return columns.size();
}
@Override
public synchronized String getName() {
return name;
}
@Override
public synchronized long getColumnFlags(int i) {
if(i>=columns.size()){
return 0;
}
return columns.get(i).getFlags();
}
@Override
public synchronized void setColumnFlags(int i,long flags){
if(i>=columns.size()){
return;
}
columns.get(i).setFlags(flags);
}
@Override
public synchronized String getColumnDescription(int col) {
if(col>=columns.size()){
return null;
}
return columns.get(col).getDescription();
}
@Override
public synchronized int getColumnImmutableId(int col){
if(col>=columns.size()){
return -1;
}
return columns.get(col).getImmutableId();
}
@Override
public synchronized void setColumnDescription(int col, String description) {
if(col>=columns.size()){
return;
}
columns.get(col).setDescription(description);
}
@Override
public synchronized int addColumn(int id, String name, ODLColumnType type, long flags){
name = Strings.removeExportIllegalChars(name);
if(TableUtils.findColumnIndx(this, name, true)!=-1){
return -1;
}
T col = createColObj(id,name,type,flags);
columns.add(col);
return columns.size()-1;
}
protected abstract T createColObj(int id,String name, ODLColumnType type, long flags);
@XmlTransient
@Override
public int getImmutableId() {
return id;
}
@Override
public synchronized void deleteColumn(int col) {
if(col>=columns.size()){
return;
}
columns.remove(col);
}
protected int validateNewColumnId(int id) {
if(id==-1){
id = nextColumnId();
}
for(ODLColumnDefinition column : columns){
if(column.getImmutableId()==id){
throw new RuntimeException("Duplicate column id: " + id);
}
}
return id;
}
@Override
public synchronized boolean insertColumn(int id,int col,String name, ODLColumnType type, long flags, boolean allowDuplicateNames) {
name = Strings.removeExportIllegalChars(name);
if(allowDuplicateNames == false && TableUtils.findColumnIndx(this, name, true)!=-1){
return false;
}
T column = createColObj(id,name,type,flags);
if(col < columns.size()){
columns.add(col, column);
}else{
columns.add(column);
}
return true;
}
public synchronized void setName(String name){
this.name = name;
}
@Override
public String toString(){
return JAXBUtils.toXMLString(this);
}
@Override
public synchronized java.util.Set<String> getColumnTags(int col) {
if(col>=columns.size()){
return null;
}
return columns.get(col).getTags();
}
@Override
public synchronized java.util.Set<String> getTags() {
// always return a copy so it can't be modified outside (don't use an unmodifiable collection as jaxb can't handle this)
if (tags != null) {
return new TreeSet<String>(tags);
}
return null;
}
@XmlElement(name="Tag")
@Override
public synchronized void setTags(Set<String> tags) {
this.tags = tags;
}
@Override
public synchronized void setColumnTags(int col, Set<String> tags) {
if(col>=columns.size()){
return;
}
columns.get(col).setTags(tags);
}
public int nextColumnId(){
return columnIdGenerator.generateId();
}
}