/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.clearsilver.jsilver.adaptor;
import com.google.clearsilver.jsilver.JSilverOptions;
import com.google.clearsilver.jsilver.data.Data;
import com.google.clearsilver.jsilver.data.DataFactory;
import com.google.clearsilver.jsilver.data.Parser;
import com.google.clearsilver.jsilver.exceptions.JSilverBadSyntaxException;
import org.clearsilver.CSFileLoader;
import org.clearsilver.HDF;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.Date;
import java.util.TimeZone;
/**
* Adaptor that wraps a JSilver Data object so it can be used as an HDF object.
*/
public class JHdf implements HDF {
// Only changed to null on close()
private Data data;
private final DataFactory dataFactory;
private final JSilverOptions options;
private final LoadPathToFileCache loadPathCache;
private ResourceLoaderAdaptor resourceLoader;
JHdf(Data data, DataFactory dataFactory, LoadPathToFileCache loadPathCache, JSilverOptions options) {
this.data = data;
this.loadPathCache = loadPathCache;
this.dataFactory = dataFactory;
this.options = options;
this.resourceLoader = new ResourceLoaderAdaptor(this, loadPathCache, null);
}
static JHdf cast(HDF hdf) {
if (!(hdf instanceof JHdf)) {
throw new IllegalArgumentException("HDF object not of type JHdf. "
+ "Make sure you use the same ClearsilverFactory to construct all "
+ "related HDF and CS objects.");
}
return (JHdf) hdf;
}
Data getData() {
return data;
}
ResourceLoaderAdaptor getResourceLoaderAdaptor() {
return resourceLoader;
}
@Override
public void close() {
// This looks pointless but it actually reduces the lifetime of the large
// Data object as far as the garbage collector is concerned and
// dramatically improves performance.
data = null;
}
@Override
public boolean readFile(String filename) throws IOException {
dataFactory.loadData(filename, resourceLoader, data);
return false;
}
@Override
public CSFileLoader getFileLoader() {
return resourceLoader.getCSFileLoader();
}
@Override
public void setFileLoader(CSFileLoader fileLoader) {
this.resourceLoader = new ResourceLoaderAdaptor(this, loadPathCache, fileLoader);
}
@Override
public boolean writeFile(String filename) throws IOException {
FileWriter writer = new FileWriter(filename);
try {
data.write(writer, 2);
} finally {
writer.close();
}
return true;
}
@Override
public boolean readString(String content) {
Parser hdfParser = dataFactory.getParser();
try {
hdfParser.parse(new StringReader(content), data, new Parser.ErrorHandler() {
public void error(int line, String lineContent, String fileName, String errorMessage) {
throw new JSilverBadSyntaxException("HDF parsing error : '" + errorMessage + "'",
lineContent, fileName, line, JSilverBadSyntaxException.UNKNOWN_POSITION, null);
}
}, resourceLoader, null, options.getIgnoreAttributes());
return true;
} catch (IOException e) {
return false;
}
}
@Override
public int getIntValue(String hdfName, int defaultValue) {
return data.getIntValue(hdfName, defaultValue);
}
@Override
public String getValue(String hdfName, String defaultValue) {
return data.getValue(hdfName, defaultValue);
}
@Override
public void setValue(String hdfName, String value) {
data.setValue(hdfName, value);
}
@Override
public void removeTree(String hdfName) {
data.removeTree(hdfName);
}
@Override
public void setSymLink(String hdfNameSrc, String hdfNameDest) {
data.setSymlink(hdfNameSrc, hdfNameDest);
}
@Override
public void exportDate(String hdfName, TimeZone timeZone, Date date) {
throw new UnsupportedOperationException("TBD");
}
@Override
public void exportDate(String hdfName, String tz, int tt) {
throw new UnsupportedOperationException("TBD");
}
@Override
public HDF getObj(String hdfpath) {
Data d = data.getChild(hdfpath);
return d == null ? null : new JHdf(d, dataFactory, loadPathCache, options);
}
@Override
public HDF getChild(String hdfpath) {
Data d = data.getChild(hdfpath);
if (d == null) {
return null;
}
for (Data child : d.getChildren()) {
if (child.isFirstSibling()) {
return new JHdf(child, dataFactory, loadPathCache, options);
} else {
// The first child returned should be the first sibling. Throw an error
// if not.
throw new IllegalStateException("First child was not first sibling.");
}
}
return null;
}
@Override
public HDF getRootObj() {
Data root = data.getRoot();
if (root == data) {
return this;
} else {
return new JHdf(root, dataFactory, loadPathCache, options);
}
}
@Override
public boolean belongsToSameRoot(HDF hdf) {
JHdf jHdf = cast(hdf);
return this.data.getRoot() == jHdf.data.getRoot();
}
@Override
public HDF getOrCreateObj(String hdfpath) {
return new JHdf(data.createChild(hdfpath), dataFactory, loadPathCache, options);
}
@Override
public String objName() {
return data.getName();
}
@Override
public String objValue() {
return data.getValue();
}
@Override
public HDF objChild() {
for (Data child : data.getChildren()) {
if (child.isFirstSibling()) {
return new JHdf(child, dataFactory, loadPathCache, options);
}
}
return null;
}
@Override
public HDF objNext() {
Data next = data.getNextSibling();
return next == null ? null : new JHdf(next, dataFactory, loadPathCache, options);
}
@Override
public void copy(String hdfpath, HDF src) {
JHdf srcJHdf = cast(src);
if (hdfpath.equals("")) {
data.copy(srcJHdf.data);
} else {
data.copy(hdfpath, srcJHdf.data);
}
}
@Override
public String dump() {
StringBuilder sb = new StringBuilder();
try {
data.write(sb, 0);
return sb.toString();
} catch (IOException e) {
return null;
}
}
@Override
public String writeString() {
return dump();
}
@Override
public String toString() {
return dump();
}
/**
* JSilver-specific method that optimizes the underlying data object. Should only be used on
* long-lived HDF objects (e.g. global HDF).
*/
public void optimize() {
data.optimize();
}
}