/*******************************************************************************
* 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 3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
******************************************************************************/
package com.opendoorlogistics.core.tables.decorators.datastores.deepcopying;
import java.util.ArrayList;
import java.util.Iterator;
import com.opendoorlogistics.api.tables.ODLDatastore;
import com.opendoorlogistics.api.tables.ODLDatastoreAlterable;
import com.opendoorlogistics.api.tables.ODLListener;
import com.opendoorlogistics.api.tables.ODLTable;
import com.opendoorlogistics.api.tables.ODLTableAlterable;
import com.opendoorlogistics.api.tables.ODLTableDefinition;
import com.opendoorlogistics.api.tables.ODLTableReadOnly;
import com.opendoorlogistics.core.tables.decorators.datastores.SimpleAbstractDecorator;
import com.opendoorlogistics.core.tables.memory.ODLDatastoreImpl;
import com.opendoorlogistics.core.tables.memory.ODLTableDefinitionImpl;
import com.opendoorlogistics.core.tables.memory.ODLTableImpl;
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;
class OptimisedDeepCopy<T extends ODLTableDefinition> extends SimpleAbstractDecorator<T>{
private class TableHolder{
T table;
boolean isImmutable;
}
private final ArrayList<TableHolder> tables = new ArrayList<>();
private long flags;
OptimisedDeepCopy(long flags) {
this.flags = flags;
}
void addImmutableTable(T table){
TableHolder h = new TableHolder();
h.isImmutable = true;
h.table = table;
tables.add(h);
}
protected final IntIDGenerator tableIdGenerator = new IntIDGenerator(new IsExistingId() {
@Override
public boolean isExistingId(int id) {
return getTableHolder(id,false)!=null;
}
});
@SuppressWarnings("unchecked")
private synchronized TableHolder getTableHolder(int id, boolean makeWritable){
int n = tables.size();
for(int i =0 ; i< n ; i++){
TableHolder h = tables.get(i);
// only take a deep copy when we need to
// TO DO .. .this looks like we could optimise this by placing this within the return,
// but we need to check for any adverse effects...
if(makeWritable && h.isImmutable){
h.table = (T)h.table.deepCopyWithShallowValueCopy();
h.isImmutable = false;
}
if(h.table.getImmutableId()==id){
return h;
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public T createTable(String tablename, int id) {
if(TableUtils.findTableIndex(this, tablename, true)!=-1){
throw new RuntimeException("Table already exists: " + tablename);
}
// get id
if(id==-1){
id = tableIdGenerator.generateId();
}
else if(getTableHolder(id, false)!=null){
throw new RuntimeException("Duplicate table id");
}
TableHolder h = new TableHolder();
h.isImmutable = false;
h.table = (T) new ODLTableImpl(id, tablename);
ODLDatastoreImpl.grantDefaultTablePermissions(this, h.table);
tables.add(h);
return getTableByImmutableId(id);
}
@Override
public void deleteTableById(int tableId) {
Iterator<TableHolder> it = tables.iterator();
while(it.hasNext()){
if(it.next().table.getImmutableId()==tableId){
it.remove();
}
}
}
@Override
public boolean setTableName(int tableId, String newName) {
// check name not already used by another table
for(TableHolder h : tables){
if(h.table.getImmutableId()!=tableId && Strings.equalsStd(h.table.getName(), newName)){
return false;
}
}
TableHolder h = getTableHolder(tableId, true);
if(h!=null && ODLTableDefinitionImpl.class.isInstance(h.table)){
((ODLTableDefinitionImpl)h.table).setName(newName);
return true;
}
return false;
}
@Override
public void setFlags(long flags) {
this.flags = flags;
}
@Override
public int getTableCount() {
return tables.size();
}
@Override
public T getTableAt(int i) {
return super.getTableByImmutableId(tables.get(i).table.getImmutableId());
}
@Override
public void addListener(ODLListener tml, int... tableIds) {
// TODO Auto-generated method stub
}
@Override
public void removeListener(ODLListener tml) {
// TODO Auto-generated method stub
}
@Override
public void disableListeners() {
// TODO Auto-generated method stub
}
@Override
public void enableListeners() {
// TODO Auto-generated method stub
}
@Override
public void startTransaction() {
// TODO Auto-generated method stub
}
@Override
public void endTransaction() {
// TODO Auto-generated method stub
}
@Override
public boolean isInTransaction() {
// TODO Auto-generated method stub
return false;
}
@Override
public void rollbackTransaction() {
// TODO Auto-generated method stub
}
@Override
public boolean isRollbackSupported() {
// TODO Auto-generated method stub
return false;
}
@Override
public long getFlags() {
return flags;
}
@Override
protected ODLTableReadOnly readOnlyTable(int tableId) {
TableHolder h = getTableHolder(tableId,false);
if(h!=null){
return (ODLTableReadOnly)h.table;
}
return null;
}
@Override
protected ODLTableDefinition definition(int tableId) {
TableHolder h = getTableHolder(tableId,false);
if(h!=null){
return (ODLTableDefinition)h.table;
}
return null;
}
@Override
protected ODLTable writable(int tableId) {
TableHolder h = getTableHolder(tableId,true);
if(h!=null){
return (ODLTable)h.table;
}
return null;
}
@Override
protected ODLTableAlterable alterable(int tableId) {
TableHolder h = getTableHolder(tableId,true);
if(h!=null){
return (ODLTableAlterable)h.table;
}
return null;
}
@Override
public boolean getTableExists(int tableId) {
return getTableHolder(tableId, false)!=null;
}
@Override
public ODLTableDefinition deepCopyWithShallowValueCopy(int tableId) {
throw new UnsupportedOperationException();
}
@Override
public ODLDatastoreAlterable<? extends T> deepCopyWithShallowValueCopy(boolean createLazyCopy) {
throw new UnsupportedOperationException();
}
}