Update of /cvsroot/jrobin/src/org/jrobin/core In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15592/src/org/jrobin/core Added Files: Tag: release-1-5-2 ArcDef.java ArcState.java Archive.java ConsolFuns.java DataImporter.java Datasource.java DsDef.java DsTypes.java FetchData.java FetchRequest.java Header.java Robin.java RrdAllocator.java RrdBackend.java RrdBackendFactory.java RrdDb.java RrdDbPool.java RrdDef.java RrdDefTemplate.java RrdDouble.java RrdDoubleArray.java RrdException.java RrdFileBackend.java RrdFileBackendFactory.java RrdInt.java RrdLong.java RrdMemoryBackend.java RrdMemoryBackendFactory.java RrdNioBackend.java RrdNioBackendFactory.java RrdPrimitive.java RrdSafeFileBackend.java RrdSafeFileBackendFactory.java RrdString.java RrdToolReader.java RrdToolkit.java RrdUpdater.java Sample.java Util.java XmlReader.java XmlTemplate.java XmlWriter.java Log Message: fix import conflicts --- NEW FILE: FetchData.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import org.jrobin.data.Aggregates; import org.jrobin.data.DataProcessor; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; /** * Class used to represent data fetched from the RRD. * Object of this class is created when the method * {@link org.jrobin.core.FetchRequest#fetchData() fetchData()} is * called on a {@link org.jrobin.core.FetchRequest FetchRequest} object.<p> * * Data returned from the RRD is, simply, just one big table filled with * timestamps and corresponding datasource values. * Use {@link #getRowCount() getRowCount()} method to count the number * of returned timestamps (table rows).<p> * * The first table column is filled with timestamps. Time intervals * between consecutive timestamps are guaranteed to be equal. Use * {@link #getTimestamps() getTimestamps()} method to get an array of * timestamps returned.<p> * * Remaining columns are filled with datasource values for the whole timestamp range, * on a column-per-datasource basis. Use {@link #getColumnCount() getColumnCount()} to find * the number of datasources and {@link #getValues(int) getValues(i)} method to obtain * all values for the i-th datasource. Returned datasource values correspond to * the values returned with {@link #getTimestamps() getTimestamps()} method.<p> * */ public class FetchData implements ConsolFuns { // anything fuuny will do private static final String RPN_SOURCE_NAME = "WHERE THE SPEECHLES UNITE IN A SILENT ACCORD"; private FetchRequest request; private String[] dsNames; private long[] timestamps; private double[][] values; private Archive matchingArchive; private long arcStep; private long arcEndTime; FetchData(Archive matchingArchive, FetchRequest request) throws IOException { this.matchingArchive = matchingArchive; this.arcStep = matchingArchive.getArcStep(); this.arcEndTime = matchingArchive.getEndTime(); this.dsNames = request.getFilter(); if (this.dsNames == null) { this.dsNames = matchingArchive.getParentDb().getDsNames(); } this.request = request; } void setTimestamps(long[] timestamps) { this.timestamps = timestamps; } void setValues(double[][] values) { this.values = values; } /** * Returns the number of rows fetched from the corresponding RRD. * Each row represents datasource values for the specific timestamp. * * @return Number of rows. */ public int getRowCount() { return timestamps.length; } /** * Returns the number of columns fetched from the corresponding RRD. * This number is always equal to the number of datasources defined * in the RRD. Each column represents values of a single datasource. * * @return Number of columns (datasources). */ public int getColumnCount() { return dsNames.length; } /** * Returns an array of timestamps covering the whole range specified in the * {@link FetchRequest FetchReguest} object. * * @return Array of equidistant timestamps. */ public long[] getTimestamps() { return timestamps; } /** * Returns the step with which this data was fetched. * * @return Step as long. */ public long getStep() { return timestamps[1] - timestamps[0]; } /** * Returns all archived values for a single datasource. * Returned values correspond to timestamps * returned with {@link #getTimestamps() getTimestamps()} method. * * @param dsIndex Datasource index. * @return Array of single datasource values. */ public double[] getValues(int dsIndex) { return values[dsIndex]; } /** * Returns all archived values for all datasources. * Returned values correspond to timestamps * returned with {@link #getTimestamps() getTimestamps()} method. * * @return Two-dimensional aray of all datasource values. */ public double[][] getValues() { return values; } /** * Returns all archived values for a single datasource. * Returned values correspond to timestamps * returned with {@link #getTimestamps() getTimestamps()} method. * * @param dsName Datasource name. * @return Array of single datasource values. * @throws RrdException Thrown if no matching datasource name is found. */ public double[] getValues(String dsName) throws RrdException { for (int dsIndex = 0; dsIndex < getColumnCount(); dsIndex++) { if (dsName.equals(dsNames[dsIndex])) { return getValues(dsIndex); } } throw new RrdException("Datasource [" + dsName + "] not found"); } /** * Returns a set of values created by applying RPN expression to the fetched data. * For example, if you have two datasources named <code>x</code> and <code>y</code> * in this FetchData and you want to calculate values for <code>(x+y)/2<code> use something like: <p> * <code>getRpnValues("x,y,+,2,/");</code><p> * @param rpnExpression RRDTool-like RPN expression * @return Calculated values * @throws RrdException Thrown if invalid RPN expression is supplied */ public double[] getRpnValues(String rpnExpression) throws RrdException { DataProcessor dataProcessor = createDataProcessor(rpnExpression); return dataProcessor.getValues(RPN_SOURCE_NAME); } /** * Returns {@link FetchRequest FetchRequest} object used to create this FetchData object. * * @return Fetch request object. */ public FetchRequest getRequest() { return request; } /** * Returns the first timestamp in this FetchData object. * * @return The smallest timestamp. */ public long getFirstTimestamp() { return timestamps[0]; } /** * Returns the last timestamp in this FecthData object. * * @return The biggest timestamp. */ public long getLastTimestamp() { return timestamps[timestamps.length - 1]; } /** * Returns Archive object which is determined to be the best match for the * timestamps specified in the fetch request. All datasource values are obtained * from round robin archives belonging to this archive. * * @return Matching archive. */ public Archive getMatchingArchive() { return matchingArchive; } /** * Returns array of datasource names found in the corresponding RRD. If the request * was filtered (data was fetched only for selected datasources), only datasources selected * for fetching are returned. * * @return Array of datasource names. */ public String[] getDsNames() { return dsNames; } /** * Retrieve the table index number of a datasource by name. Names are case sensitive. * * @param dsName Name of the datasource for which to find the index. * @return Index number of the datasources in the value table. */ public int getDsIndex(String dsName) { // Let's assume the table of dsNames is always small, so it is not necessary to use a hashmap for lookups for (int i = 0; i < dsNames.length; i++) { if (dsNames[i].equals(dsName)) { return i; } } return -1; // Datasource not found ! } /** * Dumps the content of the whole FetchData object. Useful for debugging. */ public String dump() { StringBuffer buffer = new StringBuffer(""); for (int row = 0; row < getRowCount(); row++) { buffer.append(timestamps[row]); buffer.append(": "); for(int dsIndex = 0; dsIndex < getColumnCount(); dsIndex++) { buffer.append(Util.formatDouble(values[dsIndex][row], true)); buffer.append(" "); } buffer.append("\n"); } return buffer.toString(); } /** * Returns string representing fetched data in a RRDTool-like form. * * @return Fetched data as a string in a rrdfetch-like output form. */ public String toString() { // print header row StringBuffer buff = new StringBuffer(); buff.append(padWithBlanks("", 10)); buff.append(" "); for (int i = 0; i < dsNames.length; i++) { buff.append(padWithBlanks(dsNames[i], 18)); } buff.append("\n \n"); for (int i = 0; i < timestamps.length; i++) { buff.append(padWithBlanks("" + timestamps[i], 10)); buff.append(":"); for (int j = 0; j < dsNames.length; j++) { double value = values[j][i]; String valueStr = Double.isNaN(value) ? "nan" : Util.formatDouble(value); buff.append(padWithBlanks(valueStr, 18)); } buff.append("\n"); } return buff.toString(); } private static String padWithBlanks(String input, int width) { StringBuffer buff = new StringBuffer(""); int diff = width - input.length(); while (diff-- > 0) { buff.append(' '); } buff.append(input); return buff.toString(); } /** * Returns single aggregated value from the fetched data for a single datasource. * * @param dsName Datasource name * @param consolFun Consolidation function to be applied to fetched datasource values. * Valid consolidation functions are "MIN", "MAX", "LAST", "FIRST", "AVERAGE" and "TOTAL" * (these string constants are conveniently defined in the {@link ConsolFuns} class) * @return MIN, MAX, LAST, FIRST, AVERAGE or TOTAL value calculated from the fetched data * for the given datasource name * @throws RrdException Thrown if the given datasource name cannot be found in fetched data. */ public double getAggregate(String dsName, String consolFun) throws RrdException { DataProcessor dp = createDataProcessor(null); return dp.getAggregate(dsName, consolFun); } /** * Returns aggregated value from the fetched data for a single datasource. * Before applying aggregation functions, specified RPN expression is applied to fetched data. * For example, if you have a gauge datasource named 'foots' but you want to find the maximum * fetched value in meters use something like: <p> * <code>getAggregate("foots", "MAX", "foots,0.3048,*");</code><p> * @param dsName Datasource name * @param consolFun Consolidation function (MIN, MAX, LAST, FIRST, AVERAGE or TOTAL) * @param rpnExpression RRDTool-like RPN expression * @return Aggregated value * @throws RrdException Thrown if the given datasource name cannot be found in fetched data, or if * invalid RPN expression is supplied * @throws IOException Thrown in case of I/O error (unlikely to happen) * @deprecated This method is preserved just for backward compatibility. */ public double getAggregate(String dsName, String consolFun, String rpnExpression) throws RrdException, IOException { // for backward compatibility rpnExpression = rpnExpression.replaceAll("value", dsName); return getRpnAggregate(rpnExpression, consolFun); } /** * Returns aggregated value for a set of values calculated by applying an RPN expression to the * fetched data. For example, if you have two datasources named <code>x</code> and <code>y</code> * in this FetchData and you want to calculate MAX value of <code>(x+y)/2<code> use something like: <p> * <code>getRpnAggregate("x,y,+,2,/", "MAX");</code><p> * @param rpnExpression RRDTool-like RPN expression * @param consolFun Consolidation function (MIN, MAX, LAST, FIRST, AVERAGE or TOTAL) * @return Aggregated value * @throws RrdException Thrown if invalid RPN expression is supplied */ public double getRpnAggregate(String rpnExpression, String consolFun) throws RrdException { DataProcessor dataProcessor = createDataProcessor(rpnExpression); return dataProcessor.getAggregate(RPN_SOURCE_NAME, consolFun); } /** * Returns all aggregated values (MIN, MAX, LAST, FIRST, AVERAGE or TOTAL) calculated from the fetched data * for a single datasource. * * @param dsName Datasource name. * @return Simple object containing all aggregated values. * @throws RrdException Thrown if the given datasource name cannot be found in the fetched data. */ public Aggregates getAggregates(String dsName) throws RrdException { DataProcessor dataProcessor = createDataProcessor(null); return dataProcessor.getAggregates(dsName); } /** * Returns all aggregated values for a set of values calculated by applying an RPN expression to the * fetched data. For example, if you have two datasources named <code>x</code> and <code>y</code> * in this FetchData and you want to calculate MIN, MAX, LAST, FIRST, AVERAGE and TOTAL value * of <code>(x+y)/2<code> use something like: <p> * <code>getRpnAggregates("x,y,+,2,/");</code><p> * @param rpnExpression RRDTool-like RPN expression * @return Object containing all aggregated values * @throws RrdException Thrown if invalid RPN expression is supplied */ public Aggregates getRpnAggregates(String rpnExpression) throws RrdException, IOException { DataProcessor dataProcessor = createDataProcessor(rpnExpression); return dataProcessor.getAggregates(RPN_SOURCE_NAME); } /** * Used by ISPs which charge for bandwidth utilization on a "95th percentile" basis.<p> * * The 95th percentile is the highest source value left when the top 5% of a numerically sorted set * of source data is discarded. It is used as a measure of the peak value used when one discounts * a fair amount for transitory spikes. This makes it markedly different from the average.<p> * * Read more about this topic at:<p> * <a href="http://www.red.net/support/resourcecentre/leasedline/percentile.php">Rednet</a> or<br> * <a href="http://www.bytemark.co.uk/support/tech/95thpercentile.html">Bytemark</a>. * * @param dsName Datasource name * @return 95th percentile of fetched source values * @throws RrdException Thrown if invalid source name is supplied */ public double get95Percentile(String dsName) throws RrdException { DataProcessor dataProcessor = createDataProcessor(null); return dataProcessor.get95Percentile(dsName); } /** * Same as {@link #get95Percentile(String)}, but for a set of values calculated with the given * RPN expression. * @param rpnExpression RRDTool-like RPN expression * @return 95-percentile * @throws RrdException Thrown if invalid RPN expression is supplied */ public double getRpn95Percentile(String rpnExpression) throws RrdException { DataProcessor dataProcessor = createDataProcessor(rpnExpression); return dataProcessor.get95Percentile(RPN_SOURCE_NAME); } /** * Dumps fetch data to output stream in XML format. * * @param outputStream Output stream to dump fetch data to * @throws IOException Thrown in case of I/O error */ public void exportXml(OutputStream outputStream) throws IOException { XmlWriter writer = new XmlWriter(outputStream); writer.startTag("fetch_data"); writer.startTag("request"); writer.writeTag("file", request.getParentDb().getPath()); writer.writeComment(Util.getDate(request.getFetchStart())); writer.writeTag("start", request.getFetchStart()); writer.writeComment(Util.getDate(request.getFetchEnd())); writer.writeTag("end", request.getFetchEnd()); writer.writeTag("resolution", request.getResolution()); writer.writeTag("cf", request.getConsolFun()); writer.closeTag(); // request writer.startTag("datasources"); for (int i = 0; i < dsNames.length; i++) { writer.writeTag("name", dsNames[i]); } writer.closeTag(); // datasources writer.startTag("data"); for (int i = 0; i < timestamps.length; i++) { writer.startTag("row"); writer.writeComment(Util.getDate(timestamps[i])); writer.writeTag("timestamp", timestamps[i]); writer.startTag("values"); for (int j = 0; j < dsNames.length; j++) { writer.writeTag("v", values[j][i]); } writer.closeTag(); // values writer.closeTag(); // row } writer.closeTag(); // data writer.closeTag(); // fetch_data writer.flush(); } /** * Dumps fetch data to file in XML format. * * @param filepath Path to destination file * @throws IOException Thrown in case of I/O error */ public void exportXml(String filepath) throws IOException { OutputStream outputStream = null; try { outputStream = new FileOutputStream(filepath); exportXml(outputStream); } finally { if (outputStream != null) { outputStream.close(); } } } /** * Dumps fetch data in XML format. * * @return String containing XML formatted fetch data * @throws IOException Thrown in case of I/O error */ public String exportXml() throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); exportXml(outputStream); return outputStream.toString(); } /** * Returns the step of the corresponding RRA archive * @return Archive step in seconds */ public long getArcStep() { return arcStep; } /** * Returns the timestamp of the last populated slot in the corresponding RRA archive * @return Timestamp in seconds */ public long getArcEndTime() { return arcEndTime; } private DataProcessor createDataProcessor(String rpnExpression) throws RrdException { DataProcessor dataProcessor = new DataProcessor(request.getFetchStart(), request.getFetchEnd()); for(int i = 0; i < dsNames.length; i++) { dataProcessor.addDatasource(dsNames[i], this); } if(rpnExpression != null) { dataProcessor.addDatasource(RPN_SOURCE_NAME, rpnExpression); try { dataProcessor.processData(); } catch(IOException ioe) { // highly unlikely, since all datasources have already calculated values throw new RuntimeException("Impossible error: " + ioe); } } return dataProcessor; } } --- NEW FILE: RrdFileBackend.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileLock; import java.util.HashSet; import java.util.Set; /** * JRobin backend which is used to store RRD data to ordinary files on the disk. This was the * default factory before 1.4.0 version<p> * <p/> * This backend is based on the RandomAccessFile class (java.io.* package). */ public class RrdFileBackend extends RrdBackend { private static final long LOCK_DELAY = 100; // 0.1sec private static Set<String> openFiles = new HashSet<String>(); /** read/write file status */ protected boolean readOnly; /** locking mode */ protected int lockMode; /** radnom access file handle */ protected RandomAccessFile file; /** file lock */ protected FileLock fileLock; /** * Creates RrdFileBackend object for the given file path, backed by RandomAccessFile object. * @param path Path to a file * @param readOnly True, if file should be open in a read-only mode. False otherwise * @param lockMode Locking mode, as described in {@link RrdDb#getLockMode()} * @throws IOException Thrown in case of I/O error */ protected RrdFileBackend(String path, boolean readOnly, int lockMode) throws IOException { super(path); this.readOnly = readOnly; this.lockMode = lockMode; file = new RandomAccessFile(path, readOnly ? "r" : "rw"); try { lockFile(); registerWriter(); } catch(IOException ioe) { close(); throw ioe; } } private void lockFile() throws IOException { switch (lockMode) { case RrdDb.EXCEPTION_IF_LOCKED: fileLock = file.getChannel().tryLock(); if (fileLock == null) { // could not obtain lock throw new IOException("Access denied. " + "File [" + getPath() + "] already locked"); } break; case RrdDb.WAIT_IF_LOCKED: while (fileLock == null) { fileLock = file.getChannel().tryLock(); if (fileLock == null) { // could not obtain lock, wait a little, than try again try { Thread.sleep(LOCK_DELAY); } catch (InterruptedException e) { // NOP } } } break; case RrdDb.NO_LOCKS: break; } } private void registerWriter() throws IOException { if (!readOnly) { String path = getPath(); String canonicalPath = getCanonicalPath(path); synchronized (openFiles) { if (openFiles.contains(canonicalPath)) { throw new IOException("File \"" + path + "\" already open for R/W access. " + "You cannot open the same file for R/W access twice"); } else { openFiles.add(canonicalPath); } } } } /** * Closes the underlying RRD file. * * @throws IOException Thrown in case of I/O error */ public void close() throws IOException { unregisterWriter(); try { unlockFile(); } finally { file.close(); } } private void unlockFile() throws IOException { if (fileLock != null) { fileLock.release(); } } private void unregisterWriter() throws IOException { if (!readOnly) { String path = getPath(); String canonicalPath = getCanonicalPath(path); synchronized (openFiles) { openFiles.remove(canonicalPath); } } } /** * Returns canonical path to the file on the disk. * * @param path File path * @return Canonical file path * @throws IOException Thrown in case of I/O error */ public static String getCanonicalPath(String path) throws IOException { return Util.getCanonicalPath(path); } /** * Returns canonical path to the file on the disk. * * @return Canonical file path * @throws IOException Thrown in case of I/O error */ public String getCanonicalPath() throws IOException { return RrdFileBackend.getCanonicalPath(getPath()); } /** * Writes bytes to the underlying RRD file on the disk * * @param offset Starting file offset * @param b Bytes to be written. * @throws IOException Thrown in case of I/O error */ protected void write(long offset, byte[] b) throws IOException { file.seek(offset); file.write(b); } /** * Reads a number of bytes from the RRD file on the disk * * @param offset Starting file offset * @param b Buffer which receives bytes read from the file. * @throws IOException Thrown in case of I/O error. */ protected void read(long offset, byte[] b) throws IOException { file.seek(offset); if (file.read(b) != b.length) { throw new IOException("Not enough bytes available in file " + getPath()); } } /** * Returns RRD file length. * * @return File length. * @throws IOException Thrown in case of I/O error. */ public long getLength() throws IOException { return file.length(); } /** * Sets length of the underlying RRD file. This method is called only once, immediately * after a new RRD file gets created. * * @param length Length of the RRD file * @throws IOException Thrown in case of I/O error. */ protected void setLength(long length) throws IOException { file.setLength(length); } } --- NEW FILE: RrdFileBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; /** * Factory class which creates actual {@link RrdFileBackend} objects. This was the default * backend factory in JRobin before 1.4.0 release. */ public class RrdFileBackendFactory extends RrdBackendFactory { /** factory name, "FILE" */ public static final String NAME = "FILE"; /** * Creates RrdFileBackend object for the given file path. * @param path File path * @param readOnly True, if the file should be accessed in read/only mode. * False otherwise. * @param lockMode One of the following constants: {@link RrdDb#NO_LOCKS}, * {@link RrdDb#EXCEPTION_IF_LOCKED} or {@link RrdDb#WAIT_IF_LOCKED}. * @return RrdFileBackend object which handles all I/O operations for the given file path * @throws IOException Thrown in case of I/O error. */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { return new RrdFileBackend(path, readOnly, lockMode); } /** * Method to determine if a file with the given path already exists. * @param path File path * @return True, if such file exists, false otherwise. */ protected boolean exists(String path) { return Util.fileExists(path); } /** * Returns the name of this factory. * @return Factory name (equals to string "FILE") */ public String getFactoryName() { return NAME; } } --- NEW FILE: XmlTemplate.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.InputSource; import java.awt.*; import java.io.File; import java.io.IOException; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Class used as a base class for various XML template related classes. Class provides * methods for XML source parsing and XML tree traversing. XML source may have unlimited * number of placeholders (variables) in the format <code>${variable_name}</code>. * Methods are provided to specify variable values at runtime. * Note that this class has limited functionality: XML source gets parsed, and variable * values are collected. You have to extend this class to do something more useful.<p> */ public abstract class XmlTemplate { private static final String PATTERN_STRING = "\\$\\{(\\w+)\\}"; private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING); protected Element root; private HashMap<String, Object> valueMap = new HashMap<String, Object>(); private HashSet<Node> validatedNodes = new HashSet<Node>(); protected XmlTemplate(InputSource xmlSource) throws IOException, RrdException { root = Util.Xml.getRootElement(xmlSource); } protected XmlTemplate(String xmlString) throws IOException, RrdException { root = Util.Xml.getRootElement(xmlString); } protected XmlTemplate(File xmlFile) throws IOException, RrdException { root = Util.Xml.getRootElement(xmlFile); } /** * Removes all placeholder-value mappings. */ public void clearValues() { valueMap.clear(); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, String value) { valueMap.put(name, value); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, int value) { valueMap.put(name, new Integer(value)); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, long value) { valueMap.put(name, new Long(value)); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, double value) { valueMap.put(name, new Double(value)); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, Color value) { String r = byteToHex(value.getRed()); String g = byteToHex(value.getGreen()); String b = byteToHex(value.getBlue()); String a = byteToHex(value.getAlpha()); valueMap.put(name, "#" + r + g + b + a); } private String byteToHex(int i) { String s = Integer.toHexString(i); while(s.length() < 2) { s = "0" + s; } return s; } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, Date value) { setVariable(name, Util.getTimestamp(value)); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, Calendar value) { setVariable(name, Util.getTimestamp(value)); } /** * Sets value for a single XML template variable. Variable name should be specified * without leading '${' and ending '}' placeholder markers. For example, for a placeholder * <code>${start}</code>, specify <code>start</start> for the <code>name</code> parameter. * * @param name variable name * @param value value to be set in the XML template */ public void setVariable(String name, boolean value) { valueMap.put(name, "" + value); } /** * Searches the XML template to see if there are variables in there that * will need to be set. * * @return True if variables were detected, false if not. */ public boolean hasVariables() { return PATTERN.matcher(root.toString()).find(); } /** * Returns the list of variables that should be set in this template. * * @return List of variable names as an array of strings. */ public String[] getVariables() { ArrayList<String> list = new ArrayList<String>(); Matcher m = PATTERN.matcher(root.toString()); while (m.find()) { String var = m.group(1); if (!list.contains(var)) { list.add(var); } } return list.toArray(new String[list.size()]); } protected static Node[] getChildNodes(Node parentNode, String childName) { return Util.Xml.getChildNodes(parentNode, childName); } protected static Node[] getChildNodes(Node parentNode) { return Util.Xml.getChildNodes(parentNode, null); } protected static Node getFirstChildNode(Node parentNode, String childName) throws RrdException { return Util.Xml.getFirstChildNode(parentNode, childName); } protected boolean hasChildNode(Node parentNode, String childName) { return Util.Xml.hasChildNode(parentNode, childName); } protected String getChildValue(Node parentNode, String childName) throws RrdException { return getChildValue(parentNode, childName, true); } protected String getChildValue(Node parentNode, String childName, boolean trim) throws RrdException { String value = Util.Xml.getChildValue(parentNode, childName, trim); return resolveMappings(value); } protected String getValue(Node parentNode) { return getValue(parentNode, true); } protected String getValue(Node parentNode, boolean trim) { String value = Util.Xml.getValue(parentNode, trim); return resolveMappings(value); } private String resolveMappings(String templateValue) { if (templateValue == null) { return null; } Matcher matcher = PATTERN.matcher(templateValue); StringBuffer result = new StringBuffer(); int lastMatchEnd = 0; while (matcher.find()) { String var = matcher.group(1); if (valueMap.containsKey(var)) { // mapping found result.append(templateValue.substring(lastMatchEnd, matcher.start())); result.append(valueMap.get(var).toString()); lastMatchEnd = matcher.end(); } else { // no mapping found - this is illegal // throw runtime exception throw new IllegalArgumentException("No mapping found for template variable ${" + var + "}"); } } result.append(templateValue.substring(lastMatchEnd)); return result.toString(); } protected int getChildValueAsInt(Node parentNode, String childName) throws RrdException { String valueStr = getChildValue(parentNode, childName); return Integer.parseInt(valueStr); } protected int getValueAsInt(Node parentNode) { String valueStr = getValue(parentNode); return Integer.parseInt(valueStr); } protected long getChildValueAsLong(Node parentNode, String childName) throws RrdException { String valueStr = getChildValue(parentNode, childName); return Long.parseLong(valueStr); } protected long getValueAsLong(Node parentNode) { String valueStr = getValue(parentNode); return Long.parseLong(valueStr); } protected double getChildValueAsDouble(Node parentNode, String childName) throws RrdException { String valueStr = getChildValue(parentNode, childName); return Util.parseDouble(valueStr); } protected double getValueAsDouble(Node parentNode) { String valueStr = getValue(parentNode); return Util.parseDouble(valueStr); } protected boolean getChildValueAsBoolean(Node parentNode, String childName) throws RrdException { String valueStr = getChildValue(parentNode, childName); return Util.parseBoolean(valueStr); } protected boolean getValueAsBoolean(Node parentNode) { String valueStr = getValue(parentNode); return Util.parseBoolean(valueStr); } protected Paint getValueAsColor(Node parentNode) throws RrdException { String rgbStr = getValue(parentNode); return Util.parseColor(rgbStr); } protected boolean isEmptyNode(Node node) { // comment node or empty text node return node.getNodeName().equals("#comment") || (node.getNodeName().equals("#text") && node.getNodeValue().trim().length() == 0); } protected void validateTagsOnlyOnce(Node parentNode, String[] allowedChildNames) throws RrdException { // validate node only once if (validatedNodes.contains(parentNode)) { return; } Node[] childs = getChildNodes(parentNode); main: for (int i = 0; i < childs.length; i++) { String childName = childs[i].getNodeName(); for (int j = 0; j < allowedChildNames.length; j++) { if (allowedChildNames[j].equals(childName)) { // only one such tag is allowed allowedChildNames[j] = "<--removed-->"; continue main; } else if (allowedChildNames[j].equals(childName + "*")) { // several tags allowed continue main; } } if (!isEmptyNode(childs[i])) { throw new RrdException("Unexpected tag encountered: <" + childName + ">"); } } // everything is OK validatedNodes.add(parentNode); } } --- NEW FILE: RrdDouble.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; class RrdDouble extends RrdPrimitive { private double cache; private boolean cached = false; RrdDouble(RrdUpdater updater, boolean isConstant) throws IOException { super(updater, RrdDouble.RRD_DOUBLE, isConstant); } RrdDouble(RrdUpdater updater) throws IOException { super(updater, RrdDouble.RRD_DOUBLE, false); } void set(double value) throws IOException { if(!isCachingAllowed()) { writeDouble(value); } // caching allowed else if(!cached || !Util.equal(cache, value)) { // update cache writeDouble(cache = value); cached = true; } } double get() throws IOException { return cached? cache: readDouble(); } } --- NEW FILE: RrdUpdater.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; interface RrdUpdater { public RrdBackend getRrdBackend(); public void copyStateTo(RrdUpdater updater) throws IOException, RrdException; public RrdAllocator getRrdAllocator(); } --- NEW FILE: RrdString.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; class RrdString extends RrdPrimitive { private String cache; RrdString(RrdUpdater updater, boolean isConstant) throws IOException { super(updater, RrdPrimitive.RRD_STRING, isConstant); } RrdString(RrdUpdater updater) throws IOException { this(updater, false); } void set(String value) throws IOException { if(!isCachingAllowed()) { writeString(value); } // caching allowed else if(cache == null || !cache.equals(value)) { // update cache writeString(cache = value); } } String get() throws IOException { return (cache != null)? cache: readString(); } } --- NEW FILE: XmlWriter.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.awt.*; import java.io.File; import java.io.OutputStream; import java.io.PrintWriter; import java.util.Stack; /** * Extremely simple utility class used to create XML documents. */ public class XmlWriter { static final String INDENT_STR = " "; private PrintWriter writer; private StringBuffer indent = new StringBuffer(""); private Stack<String> openTags = new Stack<String>(); /** * Creates XmlWriter with the specified output stream to send XML code to. * @param stream Output stream which receives XML code */ public XmlWriter(OutputStream stream) { writer = new PrintWriter(stream, true); } /** * Opens XML tag * @param tag XML tag name */ public void startTag(String tag) { writer.println(indent + "<" + tag + ">"); openTags.push(tag); indent.append(INDENT_STR); } /** * Closes the corresponding XML tag */ public void closeTag() { String tag = openTags.pop(); indent.setLength(indent.length() - INDENT_STR.length()); writer.println(indent + "</" + tag + ">"); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, Object value) { if(value != null) { writer.println(indent + "<" + tag + ">" + escape(value.toString()) + "</" + tag + ">"); } else { writer.println(indent + "<" + tag + "></" + tag + ">"); } } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, int value) { writeTag(tag, "" + value); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, long value) { writeTag(tag, "" + value); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, double value, String nanString) { writeTag(tag, Util.formatDouble(value, nanString, true)); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, double value) { writeTag(tag, Util.formatDouble(value, true)); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, boolean value) { writeTag(tag, "" + value); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, Color value) { int rgb = value.getRGB() & 0xFFFFFF; writeTag(tag, "#" + Integer.toHexString(rgb).toUpperCase()); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, Font value) { startTag(tag); writeTag("name", value.getName()); int style = value.getStyle(); if((style & Font.BOLD) != 0 && (style & Font.ITALIC) != 0) { writeTag("style", "BOLDITALIC"); } else if((style & Font.BOLD) != 0) { writeTag("style", "BOLD"); } else if((style & Font.ITALIC) != 0) { writeTag("style", "ITALIC"); } else { writeTag("style", "PLAIN"); } writeTag("size", value.getSize()); closeTag(); } /** * Writes <tag>value</tag> to output stream * @param tag XML tag name * @param value value to be placed between <code><tag></code> and <code></tag></code> */ public void writeTag(String tag, File value) { writeTag(tag, value.getPath()); } /** * Flushes the output stream */ public void flush() { writer.flush(); } protected void finalize() { writer.close(); } /** * Writes XML comment to output stream * @param comment comment string */ public void writeComment(Object comment) { writer.println(indent + "<!-- " + escape(comment.toString()) + " -->"); } private static String escape(String s) { return s.replaceAll("<", "<").replaceAll(">", ">"); } } --- NEW FILE: RrdNioBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; /** * Factory class which creates actual {@link RrdNioBackend} objects. This is the default factory since * 1.4.0 version */ public class RrdNioBackendFactory extends RrdFileBackendFactory{ /** factory name, "NIO" */ public static final String NAME = "NIO"; /** See {@link #setSyncMode(int)} for explanation */ public static final int SYNC_ONCLOSE = 0; // will sync() only on close() /** See {@link #setSyncMode(int)} for explanation */ public static final int SYNC_BEFOREUPDATE = 1; /** See {@link #setSyncMode(int)} for explanation */ public static final int SYNC_AFTERUPDATE = 2; /** See {@link #setSyncMode(int)} for explanation */ public static final int SYNC_BEFOREFETCH = 3; /** See {@link #setSyncMode(int)} for explanation */ public static final int SYNC_AFTERFETCH = 4; /** See {@link #setSyncMode(int)} for explanation */ public static final int SYNC_BACKGROUND = 5; /** * Period in seconds between consecutive synchronizations when * sync-mode is set to SYNC_BACKGROUND. By default in-memory cache will be * transferred to the disc every 300 seconds (5 minutes). Default value can be * changed via {@link #setSyncPeriod(int)} method. */ public static final int DEFAULT_SYNC_PERIOD = 300; // seconds private static int syncMode = SYNC_BACKGROUND; private static int syncPeriod = DEFAULT_SYNC_PERIOD; /** * Returns the current synchronization mode between backend data in memory and data * in the persistent storage (disk file). * * @return Integer representing current synchronization mode (SYNC_ONCLOSE, * SYNC_BEFOREUPDATE, SYNC_AFTERUPDATE, SYNC_BEFOREFETCH, SYNC_AFTERFETCH or * SYNC_BACKGROUND). See {@link #setSyncMode(int)} for full explanation of these return values. */ public static int getSyncMode() { return syncMode; } /** * Sets the current synchronization mode between backend data in memory (backend cache) and * RRD data in the persistant storage (disk file).<p> * @param syncMode Desired synchronization mode. Possible values are:<p> * <ul> * <li>SYNC_ONCLOSE: synchronization will be performed only when {@link RrdDb#close()} * is called (RRD file is closed) or when {@link RrdDb#sync()} method is called. * <li>SYNC_BEFOREUPDATE: synchronization will be performed before each {@link Sample#update()} * call (right before RRD file is about to be updated). * <li>SYNC_AFTERUPDATE: synchronization will be performed after each {@link Sample#update()} * call (right after RRD file is updated). * <li>SYNC_BEFOREFETCH: synchronization will be performed before each * {@link FetchRequest#fetchData()} call (right before data is about to be fetched from a RRD file, * for example for graph creation) * <li>SYNC_AFTERFETCH: synchronization will be performed after each * {@link FetchRequest#fetchData()} call (right after data is fetched from a RRD file) * <li>SYNC_BACKGROUND (<b>default</b>): synchronization will be performed automatically * from a separate thread on a regular basis. Period of time between the two consecutive * synchronizations can be controlled with {@link #setSyncPeriod(int)}. * </ul> */ public static void setSyncMode(int syncMode) { RrdNioBackendFactory.syncMode = syncMode; } /** * Returns time between two consecutive background synchronizations. If not changed via * {@link #setSyncPeriod(int)} method call, defaults to {@link #DEFAULT_SYNC_PERIOD}. * See {@link #setSyncPeriod(int)} for more information. * @return Time in seconds between consecutive background synchronizations. */ public static int getSyncPeriod() { return syncPeriod; } /** * Sets time between consecutive background synchronizations. Method is effective only if * synchronization mode is set to SYNC_BACKGROUND. * @param syncPeriod Time in seconds between consecutive background synchronizations. */ public static void setSyncPeriod(int syncPeriod) { RrdNioBackendFactory.syncPeriod = syncPeriod; } /** * Creates RrdNioBackend object for the given file path. * @param path File path * @param readOnly True, if the file should be accessed in read/only mode. * False otherwise. * @param lockMode One of the following constants: {@link RrdDb#NO_LOCKS}, * {@link RrdDb#EXCEPTION_IF_LOCKED} or {@link RrdDb#WAIT_IF_LOCKED}. * @return RrdNioBackend object which handles all I/O operations for the given file path * @throws IOException Thrown in case of I/O error. */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { return new RrdNioBackend(path, readOnly, lockMode, syncMode, syncPeriod); } /** * Returns the name of this factory. * @return Factory name (equals to string "NIO") */ public String getFactoryName() { return NAME; } } --- NEW FILE: RrdSafeFileBackendFactory.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import java.io.IOException; /** * Factory class which creates actual {@link RrdSafeFileBackend} objects. */ public class RrdSafeFileBackendFactory extends RrdFileBackendFactory { /** factory name, "SAFE" */ public static final String NAME = "SAFE"; /** * Creates RrdSafeFileBackend object for the given file path. * @param path File path * @param readOnly True, if the file should be accessed in read/only mode. * False otherwise. * @param lockMode This parameter is ignored since this backend implements its own * locking mechanism. * @return RrdSafeFileBackend object which handles all I/O operations for the given file path * @throws IOException Thrown in case of I/O error. */ protected RrdBackend open(String path, boolean readOnly, int lockMode) throws IOException { return new RrdSafeFileBackend(path, readOnly, lockMode); } /** * Returns the name of this factory. * @return Factory name (equals to string "SAFE") */ public String getFactoryName() { return NAME; } } --- NEW FILE: XmlReader.java --- /* ============================================================ * JRobin : Pure java implementation of RRDTool's functionality * ============================================================ * * Project Info: http://www.jrobin.org * Project Lead: Sasa Markovic (sa...@jr...); * * (C) Copyright 2003-2005, by Sasa Markovic. * * Developers: Sasa Markovic (sa...@jr...) * * * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation; * either version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with this * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ package org.jrobin.core; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.io.File; import java.io.IOException; class XmlReader extends DataImporter { private Element root; private Node[] dsNodes, arcNodes; XmlReader(String xmlFilePath) throws IOException, RrdException { root = Util.Xml.getRootElement(new File(xmlFilePath)); dsNodes = Util.Xml.getChildNodes(root, "ds"); arcNodes = Util.Xml.getChildNodes(root, "rra"); ... [truncated message content] |