package er.fsadaptor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import com.webobjects.eoaccess.EOAdaptorChannel;
import com.webobjects.eoaccess.EOAdaptorContext;
import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOModel;
import com.webobjects.eoaccess.EOSQLExpression;
import com.webobjects.eoaccess.EOStoredProcedure;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.eocontrol.EOKeyValueQualifier;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.eocontrol.EOSortOrdering;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSMutableDictionary;
public final class FSAdaptorChannel extends EOAdaptorChannel {
public static boolean debug = "YES".equals(System.getProperty("FSAdaptorDebuggingEnabled"));
private static final String DefaultModelName = "FS.eomodeld";
private static final String[] TableNames = { "FSItem", "FSFile", "FSDirectory" };
private boolean _isOpen = false;
private NSArray<EOAttribute> _attributes = null;
private final NSMutableArray<File> _files = new NSMutableArray<File>();
public FSAdaptorChannel(EOAdaptorContext aContext) {
super(aContext);
}
private NSMutableArray<File> files() {
return _files;
}
@Override
public NSArray<EOAttribute> attributesToFetch() {
return _attributes;
}
@Override
public void cancelFetch() {
files().removeAllObjects();
}
@Override
public void closeChannel() {
_isOpen = false;
}
@Override
public int deleteRowsDescribedByQualifier(EOQualifier aQualifier, EOEntity anEntity) {
if (aQualifier != null) {
if (anEntity != null) {
NSArray<File> someFiles = FSQualifierHandler.filesWithQualifier(aQualifier, rootDirectory(anEntity));
if (someFiles != null) {
someFiles = filteredArrayWithEntity(someFiles, anEntity);
if (someFiles != null) {
int count = someFiles.count();
int counter = 0;
for (int index = 0; index < count; index++) {
File aFile = someFiles.objectAtIndex(index);
if (aFile.delete())
counter++;
}
return counter;
}
}
return 0;
}
throw new IllegalArgumentException("FSAdaptorChannel.deleteRowsDescribedByQualifier: null entity.");
}
throw new IllegalArgumentException("FSAdaptorChannel.deleteRowsDescribedByQualifier: null qualifier.");
}
@Override
public NSArray<EOAttribute> describeResults() {
return _attributes;
}
@Override
public void evaluateExpression(EOSQLExpression anExpression) {
throw new UnsupportedOperationException("FSAdaptorChannel.evaluateExpression");
}
@Override
public void executeStoredProcedure(EOStoredProcedure aStoredProcedure, NSDictionary someValues) {
throw new UnsupportedOperationException("FSAdaptorChannel.executeStoredProcedure");
}
@Override
public NSMutableDictionary<String, Object> fetchRow() {
File aFile = files().lastObject();
if (aFile != null) {
files().removeLastObject();
return dictionaryForFileWithAttributes(aFile, attributesToFetch());
}
return null;
}
@Override
public void insertRow(NSDictionary<String, Object> aRow, EOEntity anEntity) {
if (aRow != null) {
if (anEntity != null) {
String aPath = (String) aRow.objectForKey("absolutePath");
if (aPath != null) {
File aFile = new File(aPath);
try {
if (anEntity.externalName().equals("FSDirectory"))
aFile.mkdirs();
else
aFile.createNewFile();
} catch (Exception anException) {
throw new RuntimeException("FSAdaptorChannel.insertRow: " + anException);
}
return;
}
throw new IllegalArgumentException("FSAdaptorChannel.insertRow: null absolutePath.");
}
throw new IllegalArgumentException("FSAdaptorChannel.insertRow: null entity.");
}
throw new IllegalArgumentException("FSAdaptorChannel.insertRow: null row.");
}
@Override
public boolean isFetchInProgress() {
if (files().count() > 0)
return true;
return false;
}
@Override
public boolean isOpen() {
return _isOpen;
}
@Override
public void openChannel() {
_isOpen = true;
}
@Override
public NSDictionary returnValuesForLastStoredProcedureInvocation() {
throw new UnsupportedOperationException("FSAdaptorChannel.returnValuesForLastStoredProcedureInvocation");
}
public String rootDirectory(EOEntity entity) {
String root = (String) entity.model().connectionDictionary().objectForKey("rootDirectory");
if (root == null)
root = "";
return root;
}
@Override
public void selectAttributes(NSArray<EOAttribute> someAttributes, EOFetchSpecification aFetchSpecification, boolean shouldLock, EOEntity anEntity) {
if (anEntity == null)
throw new IllegalArgumentException("FSAdaptorChannel.selectAttributes: null entity.");
if (someAttributes == null)
throw new IllegalArgumentException("FSAdaptorChannel.selectAttributes: null attributes.");
setAttributesToFetch(someAttributes);
EOQualifier qualifier = null;
String entityName = anEntity.name();
if (aFetchSpecification != null)
qualifier = aFetchSpecification.qualifier();
if (debug)
System.out.println("*****selectAttributes: " + entityName + "--" + aFetchSpecification.entityName() + "--" + aFetchSpecification);
// if(true) throw new RuntimeException();
NSArray<File> someFiles = FSQualifierHandler.filesWithQualifier(qualifier, rootDirectory(anEntity));
if (someFiles != null) {
NSArray<EOSortOrdering> someSortOrderings = aFetchSpecification.sortOrderings();
if (someSortOrderings != null)
someFiles = EOSortOrdering.sortedArrayUsingKeyOrderArray(someFiles, someSortOrderings);
someFiles = filteredArrayWithEntity(someFiles, anEntity);
if (someFiles != null)
files().addObjectsFromArray(someFiles);
}
}
@Override
public void setAttributesToFetch(NSArray<EOAttribute> someAttributes) {
if (someAttributes != null)
_attributes = someAttributes;
else
throw new IllegalArgumentException("FSAdaptorChannel.setAttributesToFetch: null attributes.");
}
@Override
public int updateValuesInRowsDescribedByQualifier(NSDictionary aRow, EOQualifier aQualifier, EOEntity anEntity) {
if (aRow != null) {
if (aQualifier != null) {
if (anEntity != null) {
NSArray<File> someFiles = FSQualifierHandler.filesWithQualifier(aQualifier, rootDirectory(anEntity));
if (someFiles != null) {
someFiles = filteredArrayWithEntity(someFiles, anEntity);
if (someFiles != null) {
int count = someFiles.count();
for (int index = 0; index < count; index++) {
File aFile = someFiles.objectAtIndex(index);
NSArray someKeys = aRow.allKeys();
int keyCount = someKeys.count();
for (int keyIndex = 0; keyIndex < keyCount; keyIndex++) {
Object aKey = someKeys.objectAtIndex(keyIndex);
EOAttribute anAttribute = anEntity.attributeNamed(aKey.toString());
if (anAttribute != null) {
Object aValue = aRow.objectForKey(aKey);
NSKeyValueCoding.DefaultImplementation.takeValueForKey(aFile, aValue, anAttribute.columnName());
}
}
}
return count;
}
}
return 0;
}
throw new IllegalArgumentException("FSAdaptorChannel.updateValuesInRowsDescribedByQualifier: null entity.");
}
throw new IllegalArgumentException("FSAdaptorChannel.updateValuesInRowsDescribedByQualifier: null qualifier.");
}
throw new IllegalArgumentException("FSAdaptorChannel.updateValuesInRowsDescribedByQualifier: null row.");
}
private URL defaultModelUrl() {
Class aClass = this.getClass();
String aClassName = aClass.getName();
String aResourceName = "/" + aClassName.replace('.', '/') + ".class";
URL anURL = aClass.getResource(aResourceName);
if (anURL != null) {
String aPath = anURL.getFile();
String aPrefix = "file:/";
String aSeparator = "!";
int anIndex = aPath.indexOf(aPrefix);
if (anIndex != -1)
aPath = aPath.substring(anIndex - 1 + aPrefix.length(), aPath.length() - 1);
anIndex = aPath.indexOf(aSeparator);
if (anIndex != -1)
aPath = aPath.substring(0, anIndex);
File aFile = new File(aPath);
File aModelFile = new File(aFile.getParentFile().getParent() + "/FS", DefaultModelName);
if (debug) {
System.out.println(aFile);
System.out.println(aModelFile);
}
try {
return aModelFile.toURI().toURL();
} catch (MalformedURLException e) {
System.out.println(e);
}
}
return null;
}
@Override
public NSArray describeTableNames() {
return new NSArray(TableNames);
}
@Override
public EOModel describeModelWithTableNames(NSArray tableNames) {
return new EOModel(defaultModelUrl());
}
private NSArray filteredArrayWithEntity(NSArray anArray, EOEntity anEntity) {
if (anArray != null) {
if (anEntity != null) {
String anEntityName = anEntity.externalName();
if (debug)
System.out.println("filteredArrayWithEntity: " + anEntity.name() + "/" + anEntityName + " --- " + anArray);
if (!anEntityName.equals("FSItem")) {
Boolean isDirectory = Boolean.FALSE;
if (anEntityName.equals("FSDirectory"))
isDirectory = Boolean.TRUE;
anArray = (EOQualifier.filteredArrayWithQualifier(anArray, new EOKeyValueQualifier("isDirectory", (EOQualifier.QualifierOperatorEqual), isDirectory)));
}
if (anArray != null && anArray.count() > 0)
return anArray;
return null;
}
throw new IllegalArgumentException("FSAdaptorChannel.filteredArrayWithEntity: null entity.");
}
throw new IllegalArgumentException("FSAdaptorChannel.filteredArrayWithEntity: null array.");
}
private NSMutableDictionary<String, Object> dictionaryForFileWithAttributes(File aFile, NSArray<EOAttribute> someAttributes) {
if (aFile != null) {
if (someAttributes != null) {
NSMutableDictionary<String, Object> aDictionary = new NSMutableDictionary<String, Object>();
for (EOAttribute anAttribute : someAttributes) {
String columnName = anAttribute.columnName();
Object aValue = null;
if ("content".equals(columnName)) {
InputStream in = null;
try {
String path = aFile.getAbsolutePath();
in = new FileInputStream(path);
int length = in.available();
if (length == 0) {
aValue = "";
} else {
byte buffer[] = new byte[length];
in.read(buffer);
aValue = new String(buffer);
}
} catch (IOException ex) {
System.err.println("dictionaryForFileWithAttributes : (" + aFile.getName() + ") " + ex);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
}
} else if ("realFile".equals(columnName)) {
aValue = aFile;
} else {
aValue = NSKeyValueCoding.DefaultImplementation.valueForKey(aFile, columnName);
}
if (aValue == null)
aValue = NSKeyValueCoding.NullValue;
aDictionary.setObjectForKey(aValue, anAttribute.name());
}
return aDictionary;
}
throw new IllegalArgumentException("FSAdaptorChannel.dictionaryForFileWithAttributes: null attributes.");
}
throw new IllegalArgumentException("FSAdaptorChannel.dictionaryForFileWithAttributes: null file.");
}
}