All Downloads are FREE. Search and download functionalities are using the official Maven repository.

decodes.xml.XmlDatabaseIO Maven / Gradle / Ivy

Go to download

A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.

The newest version!
/*
*  $Id$
*  
*  Open Source Software
*  
*  $Log$
*  Revision 1.6  2016/02/04 18:51:01  mmaloney
*  Improved debugs.
*
*  Revision 1.5  2015/04/15 19:59:47  mmaloney
*  Fixed synchronization bugs when the same data sets are being processed by multiple
*  routing specs at the same time. Example is multiple real-time routing specs with same
*  network lists. They will all receive and decode the same data together.
*
*  Revision 1.4  2014/08/29 18:20:00  mmaloney
*  remove updateTransportId method
*
*  Revision 1.3  2014/08/22 17:23:04  mmaloney
*  6.1 Schema Mods and Initial DCP Monitor Implementation
*
*  Revision 1.2  2014/05/30 13:00:28  mmaloney
*  dev
*
*  Revision 1.1.1.1  2014/05/19 15:28:59  mmaloney
*  OPENDCS 6.0 Initial Checkin
*
*  Revision 1.17  2013/05/06 18:17:20  mmaloney
*  Bug in Platform File Name creation. DbKey is now not a number.
*
*  Revision 1.16  2013/03/21 18:27:40  mmaloney
*  DbKey Implementation
*
*/
package decodes.xml;

import ilex.util.Counter;
import ilex.util.FileCounter;
import ilex.util.Logger;
import ilex.xml.LoggerErrorHandler;
import ilex.xml.XmlObjectWriter;
import ilex.xml.XmlOutputStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import javax.xml.parsers.ParserConfigurationException;

import opendcs.dai.LoadingAppDAI;
import opendcs.dai.PlatformStatusDAI;
import opendcs.dai.ScheduleEntryDAI;

import org.xml.sax.SAXException;

import decodes.db.Constants;
import decodes.db.DataSource;
import decodes.db.DataSourceList;
import decodes.db.DataTypeSet;
import decodes.db.Database;
import decodes.db.DatabaseException;
import decodes.db.DatabaseIO;
import decodes.db.EngineeringUnitList;
import decodes.db.EnumList;
import decodes.db.EquipmentModel;
import decodes.db.EquipmentModelList;
import decodes.db.NetworkList;
import decodes.db.NetworkListList;
import decodes.db.NetworkListSpec;
import decodes.db.Platform;
import decodes.db.PlatformConfig;
import decodes.db.PlatformConfigList;
import decodes.db.PlatformList;
import decodes.db.PlatformSensor;
import decodes.db.PresentationGroup;
import decodes.db.PresentationGroupList;
import decodes.db.RoutingSpec;
import decodes.db.RoutingSpecList;
import decodes.db.Site;
import decodes.db.SiteList;
import decodes.db.SiteName;
import decodes.db.UnitConverterSet;
import decodes.sql.DbKey;
import decodes.tsdb.xml.XmlLoadingAppDAO;
import decodes.util.DecodesSettings;

/**
 * This class allows you to read database information from a
 * collection of XML files stored in a predefined directory hierarchy.
 */
public class XmlDatabaseIO extends DatabaseIO
{
	public static final String module = "XmlDatabaseIO";
	// Directory Structure for the XML Files:
	public static final String PlatformDir = "platform";
	public static final String SiteDir = "site";
	public static final String PlatformConfigDir = "config";
	public static final String RoutingSpecDir = "routing";
	public static final String EnumDir = "enum";
	public static final String EnumListFile = "EnumList.xml";
	public static final String NetworkListDir = "netlist";
	public static final String PresentationGroupDir = "presentation";
	public static final String EUDir = "eu";
	public static final String EUListFile = "EngineeringUnitList.xml";
	public static final String DataTypeDir = "datatype";
	public static final String DataTypeEquivFile = "DataTypeEquivalenceList.xml";
	public static final String PlatformListFile = "PlatformList.xml";
	public static final String PMConfigDir = "pm";
	//public static final String TimeZoneDir = "tz";
	//public static final String TimeZoneFile = "TimeZoneList.xml";
	public static final String EquipmentDir = "equipment";
	public static final String DataSourceDir = "datasource";
	public static final String ScheduleEntryDir = "schedule";
	public static final String PlatformStatusDir = "platstat";
	public static final String LoadingAppDir = "loading-app";
	
	private static String[] subdirs = { PlatformDir, SiteDir, PlatformConfigDir,
		RoutingSpecDir, EnumDir, NetworkListDir, PresentationGroupDir, EUDir,
		DataTypeDir, EquipmentDir, DataSourceDir, ScheduleEntryDir,
		PlatformStatusDir, LoadingAppDir
	};
	
	protected boolean commitAfterSelect = false;

	/**
	 * The 'root' of the tree containing the database directories
	 */
	protected String xmldir;
	protected TopLevelParser myParser;
	protected LoggerErrorHandler errorHandler;
	protected String dtdUri;
	protected FileCounter platformIdCounter;
	protected static NumberFormat platIdFormat;
	static
	{
		platIdFormat = NumberFormat.getNumberInstance();
		platIdFormat.setMaximumIntegerDigits(5);
		platIdFormat.setMinimumIntegerDigits(5);
		platIdFormat.setGroupingUsed(false);
	}

	// Switches
	public static boolean writeDependents = true;

	/**
	 * Construct with a database directory location.
	 * @param xmldir top of hierarchy of XML database
	 * @throws SAXException if can't initialize XML parsers
	 * @throws ParserConfigurationException if can't configure XML parsers
	 */
	public XmlDatabaseIO( String xmldir ) 
		throws SAXException, ParserConfigurationException
	{
		Logger.instance().log(Logger.E_DEBUG1, 
			"Creating XmlDatabaseIO for directory '" + xmldir + "'");
		this.xmldir = xmldir;
		myParser = new TopLevelParser();

		errorHandler = new LoggerErrorHandler();
		errorHandler.stopOnWarnings(false);
		errorHandler.stopOnErrors(false);
		myParser.setErrorHandler(errorHandler);
		platformIdCounter = null;

		dtdUri = null;

		if (xmldir != null && xmldir.length() > 0)
		{
			File xmlTop = new File(xmldir);
			if (!xmlTop.isDirectory())
			{
				if (!xmlTop.mkdirs())
				{
					Logger.instance().warning(module + " Top directory '" + xmldir 
						+ "' does not exist and cannot be created. Check permissions and location.");
					return;
				}
			}
			for(String subdir : subdirs)
			{
				File entdir = new File(xmlTop, subdir);
				if (!entdir.isDirectory() && !entdir.mkdir())
					Logger.instance().warning(module + " Entity directory '" + entdir.getPath() 
						+ "' does not exist and cannot be created. Check permissions and location.");
			}
		}
	}

	/**
	 * @return "XML"
	 */
	public String getDatabaseType( ) { return "XML"; }

	/**
	 * @return the top directory of the hierarchy
	 */
	public String getDatabaseName( ) { return xmldir; }

	/**
	 * @return false: XML database doesn't require login.
	 */
	public boolean requiresLogin( ) { return false; }

	/**
	 * Does nothing.
	 * @param user ignored
	 * @param passwd ignored
	 */
	public void doLogin( String user, String passwd ) {}

	/**
	 * Does nothing.
	 * @return true
	 */
	public boolean isLoggedIn( ) { return true; }

	/**
	 * Does nothing.
	*/
	public void close( )
	{
	}

	/**
	 * @return the TopLevelParser to handle the top element in the XML file.
	 */
	public TopLevelParser getParser( ) { return myParser; }


	// The following three methods are the low-level methods for creating
	// input/output streams and listing directories. The URL sub-class
	// will overload these. All other methods defined herein will then
	// work fine.

	/**
	 * Opens an input stream to read the passed file name.
	 * The root directory for the database is pre-pended.
	 * @param dir the directory
	 * @param name the file name
	 * @return @throws IOException if can't read file
	 */
	protected InputStream getInputStream( String dir, String name ) throws IOException
	{
		String fn = makePath(dir, name);
		Logger.instance().debug3("XmlDatabaseIO: Opening '" + fn + "'");
		return new FileInputStream(fn);
	}

	/**
	 * @param dir the directory
	 * @param name the file name, which may or may not end with ".xml"
	 * @return the path
	 */
	public String makePath( String dir, String name )
	{
		String fn = xmldir + File.separator + dir + File.separator + name;
		if (!fn.endsWith(".xml"))
			fn += ".xml";
		return fn;
	}


	/**
	 * Returns the last modify time for an object in this database. The
	 * read methods can use this to determine if an already-loaded copy
	 * is up-to-date.
	 * @param dir the directory
	 * @param name the file name
	 * @return msec last modify time
	 * @throws IOException if IO error.
	 */
	protected long getLastModifyTime( String dir, String name ) throws IOException
	{
		File file = new File(makePath(dir, name));
		return file.lastModified();
	}

	/** Used to select XML files */
	static FilenameFilter xmlFilenameFilter = new FilenameFilter()
		{
			public boolean accept(File dir, String name)
			{
				return name.endsWith(".xml") || name.endsWith(".XML");
			}
		};

	/**
	 * Construct a string array containing a list of files under the
	 * passed directory name.
	 * @param dir the directory within the database hierarchy
	 * @return String array of file names in that directory.
	 */
	protected String[] listDirectory( String dir ) throws IOException
	{
		File fdir = new File(xmldir + File.separatorChar + dir);
		return fdir.list(xmlFilenameFilter);
	}

	/**
	 * Open an output stream for writing to the passed file name.
	 * @param dir the directory
	 * @param name the file name
	 * @return an OutputStream
	 */
	protected OutputStream getOutputStream( String dir, String name ) throws IOException
	{
		String fn = makePath(dir, name);
		return new FileOutputStream(fn);
	}

	/**
	 * At initialization, set a URI for a DTD if there is one.
	 * @param dtdUri URI to use on output files.
	 */
	public void setDtdUri( String dtdUri ) { this.dtdUri = dtdUri; }


	/**
	 * Returns the list of PlatformConfig objects defined in this database.
	 * Parse exceptions will be added to the error handler.
	 * @param pcl object in which to store data
	 * @throws DatabaseException if can't list the directory.
	 */
	public void readConfigList( PlatformConfigList pcl ) throws DatabaseException
	{
		try
		{
			String ls[] = listDirectory(PlatformConfigDir);
			if (ls == null)
				return;

			for(int i=0; i 0 ) {
					String newSeq = String.format("%03d", seqNumber);
					String newName = prefix+"-"+newSeq;
					String xmlPath = xmldir+File.separator+PlatformConfigDir+File.separator+newName+".xml";
					File xmlFile = new File ( xmlPath );
					try {
						boolean noExistingfile=xmlFile.createNewFile();
						if ( noExistingfile ) {
							if ( pc == null )
								pc = new PlatformConfig(newName);
							else
								pc.configName = newName;
							try {
								writeConfig( pc );
							} catch (DatabaseException ex1) {
									throw new DatabaseException ("Could not save new platform configuration - "+newName);
							}
						} else {
							seqNumber = -1;
						}
 					} catch ( Exception ex2 ) {
						throw new DatabaseException ("Could not obtain sequence number for configuration starting with "+ prefix);
					}
				} else {
					throw new DatabaseException ("Could not obtain sequence number for configuration starting with "+ prefix);
				}
			} catch ( DatabaseException e ) {
					throw new DatabaseException (e.toString());
			}
		}
		return(pc);
	}

	private int nextPlatformSequence(String prefix) {
		int seqNo;
		int maxSeq = 0;
		int nextSeq = 0;
		PlatformConfig pc = null;
		try
		{
		  String ls[] = listDirectory(PlatformConfigDir);
		  if (ls == null)
		    return (0);
		  for(int i=0; i maxSeq )
							maxSeq = seqNo;
		    	}
				}
		    // Catch other type (IO or bad cast) exceptions
		    catch(Exception e)
		    {
		      String msg = "Error parsing platform config '"
		        + ls[i] + "' " + e;
		      Logger.instance().log(Logger.E_FAILURE, msg);
		    }
		    finally
		    {
		      if (is != null)
		        try { is.close(); } catch(Exception e) {}
		    }
		  }
			maxSeq++;
			int[] sequenceNumber = new int[maxSeq];
			for (int l=0; l < maxSeq; l++ )
				sequenceNumber[l] = 0;
		  for(int i=0; i getNetlistSpecs()
		throws DatabaseException
	{
		// In XML this will require parsing every network list file.
		NetworkListList nll = new NetworkListList();
		readNetworkListList(nll);
		ArrayList ret = new ArrayList();
		for(NetworkList nl : nll.getList())
			ret.add(
				new NetworkListSpec(Constants.undefinedId,
					nl.name, nl.transportMediumType,
					nl.siteNameTypePref, nl.lastModifyTime, nl.size()));
		return ret;
	}


	/**
	 * Read the platform list cross reference file and populate the passed
	 * PlatformList object.
	 * @param top object in which to store data
	 */
	public void readPlatformList( PlatformList top ) 
		throws DatabaseException
	{
		Database oldDb = Database.getDb();
		// Make sure correct database is in effect.
		Database.setDb(top.getDatabase());
		InputStream is = null;
		try
		{
			long lmt = getLastModifyTime(PlatformDir, PlatformListFile);
			if (top.getTimeLastRead() < lmt)
			{
				is = getInputStream(PlatformDir, PlatformListFile);
				myParser.parse(is, top);
				top.setTimeLastRead();
			}
		}
		catch(Exception e)
		{
			e.printStackTrace(System.err);
			throw new DatabaseException(e.toString());
		}
		finally
		{
			if (is != null)
				try { is.close(); } catch(Exception e) {}
			Database.setDb(oldDb);
		}
	}

	public Date getPlatformListLMT()
	{
		try
		{
			return new Date(
				getLastModifyTime(PlatformDir, PlatformListFile));
		}
		catch(IOException ex)
		{
			return new Date(0L);
		}
	}

	public DbKey lookupPlatformId(String mediumType, String mediumId,
		Date timeStamp)
		throws DatabaseException
	{
		
		PlatformList platList = Database.getDb().platformList;
        if (platList.getTimeLastRead() == 0L)
        {
        	readPlatformList(platList);
        }
        Platform p = platList.findPlatform(mediumType, mediumId, timeStamp);
       	if (p == null)
       	{
Logger.instance().debug3("XmlDatabaseIO: lookup - No platform matching " + mediumType + ":" + mediumId);
       		return Constants.undefinedId;
       	}
Logger.instance().debug3("XmlDatabaseIO: lookup - platformID = " + p.getId());
       	return p.getId();
	}
	
	public synchronized DbKey lookupCurrentPlatformId(SiteName sn, 
		String designator, boolean useDesignator)
		throws DatabaseException
	{
		PlatformList platList = Database.getDb().platformList;
        if (platList.getTimeLastRead() == 0L)
        {
        	readPlatformList(platList);
        }

        if (sn.getSite() == null)
        	return Constants.undefinedId;
        Platform plat = platList.findPlatform(sn.getSite(), designator);
        if (plat == null)
        	return Constants.undefinedId;
        return plat.getId();
	}
	
	/**
	 * Reads the list of all Platform objects defined in this database.
	 * Objects in this list may be only partially populated (key values
	 * and primary display attributes only).
	 * @param pl object in which to store data
	 */
	public void readAllPlatforms( PlatformList pl ) throws DatabaseException
	{
		try
		{
			String ls[] = listDirectory(PlatformDir);
			if (ls == null)
				return;
			for(int i=0; i
	 * This method searches for a file matching any of the SiteNames assigned
	 * to this site.
	 * @param site object in which to store data
	 */
	public void readSite( Site site ) throws DatabaseException
	{
		for(Iterator it = site.getNames(); it.hasNext(); )
		{
			SiteName nm = it.next();
			String fn = this.makePath(SiteDir, nm.makeFileName());
			File file = new File(fn);
			if (file.canRead())
			{
				try
				{
					myParser.parse(file, site);
					site.filename = fn;
					return;
				}
				catch(Exception e)
				{
					throw new DatabaseException("Cannot read " + fn + ": " + e);
				}
			}
		}
	}


	/**
	 * Writes site information back to the database.
	 * A file will be written in the sites subdirectory containing this
	 * object's information. The filename will be constructed from the
	 * preferred naming standard (as defined in your decodes.properties)
	 * file. If no name of that type exists, the first name assigned to
	 * this site will be used.
	 * @param site the object to write
	 * @throws DatabaseException if no name is assigned to this object or
	 * if the write fails.
	 */
	public void writeSite( Site site ) throws DatabaseException
	{
		String type = DecodesSettings.instance().siteNameTypePreference;
		SiteName sn = site.getName(type);
		if (sn == null)
		{
			for(Iterator it = site.getNames(); it.hasNext(); )
			{
				sn = it.next();
				break;
			}
			if (sn == null) // No names of any type defined!
				throw new DatabaseException("Cannot save site with no name");
		}
		String pfn = sn.makeFileName();
		String fn = xmldir + File.separator + SiteDir + File.separator + pfn;

		/*
		  If writing a site with a different name, remove the old filename.
		  This can happen in the editor if the preferred site name is changed.
		*/
		if (site.filename != null && !fn.equals(site.filename))
		{
			Logger.instance().log(Logger.E_DEBUG1,
				"XmlDatabaseIO.writeSite: Deleting old site file '"
				+ site.filename + "'");
			try
			{
				File oldFile = new File(site.filename);
				oldFile.delete();
			}
			catch(Exception ex)
			{
				Logger.instance().log(Logger.E_WARNING,
					"XmlDatabaseIO.writeSite: Cannot remove old site file '" 
					+ site.filename + "'");
			}
		}

		site.filename = fn;
		writeDatabaseObject(fn, new SiteParser(site));

		if (writeDependents)
		{
			// Rewrite any platforms that contain this site.
			int numPlatformsWritten = 0;
			for(Iterator it = Database.getDb().platformList.iterator();
				it.hasNext(); )
			{
				Platform p = it.next();
				boolean writeThis = false;
				if (p.getSite() == site)
					writeThis = true;
				else if (p.getSite() != null)
				{
					SiteName sn2 = p.getSite().getPreferredName();
					if (sn2 != null)
					{
						String pfn2 = sn2.makeFileName();
						if (pfn2.equals(pfn))
							writeThis = true;
					}
				}
				for(Iterator sit = p.getPlatformSensors(); sit.hasNext(); )
				{
					PlatformSensor ps = sit.next();
					if (ps.site == site)
					{
						writeThis = true;
						break;
					}
				}
				if (writeThis)
				{
					if (!p.isComplete())
						p.read();
					p.setSite(site);
					p.write();
					numPlatformsWritten++;
				}
			}
			if (numPlatformsWritten > 0)
				Database.getDb().platformList.write();
		}
	}


	/**
	 * Deletes a site from the database.
	 * @param site the site to write
	 */
	public void deleteSite( Site site ) throws DatabaseException
	{
		// Attempt to delete all possible file names.
		for(Iterator it = site.getNames(); it.hasNext(); )
		{
			SiteName sn = it.next();
			String fn = xmldir + File.separator + SiteDir
				+ File.separator + sn.makeFileName();
			try { tryDelete(fn); }
			catch(Exception e) {}
		}
	}
	
	public Site getSiteBySiteName(SiteName sn)
		throws DatabaseException
	{
		Site site = new Site();
		site.addName(sn);
		readSite(site);
		return site;
	}


	/**
	 * Reads a complete platform from the database.
	 * This uses this object's platformId member to
	 * uniquely identify the record in the database.
	 * 

* The resulting platform object will be populated with links to sites, * platform configs, platform sensors, and transport media. *

* @param p object in which to store data */ public void readPlatform( Platform p ) throws DatabaseException { String fn = makePath(PlatformDir, "p" + platIdFormat.format(p.getId().getValue())); Logger.instance().log(Logger.E_DEBUG1, "XmlDatabaseIO: Reading '" + fn + "'"); File file = new File(fn); if (file.canRead()) { p.lastModifyTime = new Date(file.lastModified()); try { myParser.parse(file, p); } catch(Exception ex) { String msg = "Error reading '" + fn + "': " + ex; System.err.println(msg); ex.printStackTrace(); throw new DatabaseException(msg); } Logger.instance().debug1("XML readPlatform, fileLMT=" + myParser.getFileLMT() + ", platformLMT=" + p.lastModifyTime); return; } throw new DatabaseException( "Cannot read platform from file '" + fn + "'"); } /** * Writes a complete platform back to the database. * This uses this object's platformId member to * uniquely identify the record in the database. * @param p the platform to write * @throws DatabaseException */ public void writePlatform( Platform p ) throws DatabaseException { if (!p.idIsSet()) p.setId(DbKey.createDbKey(getPlatformIdCounter().getNextValue())); String fn = makePath(PlatformDir, "p" + platIdFormat.format(p.getId().getValue())); writeDatabaseObject(fn, new PlatformParser(p)); } public static String makeFileName(Platform p) { return "p" + platIdFormat.format(p.getId().getValue()) + ".xml"; } /** * Returns Date object representing the last modify time for this * platform in the database. * Returns null if the platform no longer exists in the database. * @param p to check * @return last modify time as a Java Date object */ public Date getPlatformLMT( Platform p ) throws DatabaseException { String fn = makePath(PlatformDir, "p" + platIdFormat.format(p.getId().getValue())); File f = new File(fn); if (!f.exists()) { String msg = "Platform '" + p.makeFileName() + "' with file name '" + fn + "' has been deleted."; Logger.instance().log(Logger.E_WARNING, msg); return null; } return new Date(f.lastModified()); } /** * Writes the 'platform list' to the database. * This list is an XML file containing abbreviated entries for each * platform. Just enough to populate the Platform List tab in the editor. * @param pl the platform list */ public void writePlatformList( PlatformList pl ) throws DatabaseException { String fn = xmldir + File.separator + PlatformDir + File.separator + PlatformListFile; writeDatabaseObject(fn, new PlatformListParser(pl)); } /** * Deletes a platform from the database, including its transport * media. It's configuration is not deleted. * @param p the platform to delete */ public void deletePlatform( Platform p ) throws DatabaseException { String fn = makePath(PlatformDir, "p" + platIdFormat.format(p.getId().getValue())); try { tryDelete(fn); } catch(Exception e) {} } /** * Reads a PlatformConfig object from the database. * This uses the object's configName member to uniquely identify * it in the database (not its ID number). *

* The resulting PlatformConfig will be complete with links to config- * sensors, decodes scripts (and subordinate script data), and equipment * model. *

* @param pc object in which to store data * @throws DatabaseException */ public void readConfig( PlatformConfig pc ) throws DatabaseException { String fn = ""; try { fn = makePath(PlatformConfigDir, pc.makeFileName()); myParser.parse(new File(fn), pc); } catch(Exception e) { throw new DatabaseException("Error reading '" + fn + "': " + e); } } /** * Writes a PlatformConfig back to the database. * This uses the object's configName member to uniquely identify * it in the database (not its ID number). * @param ob object to write * @throws DatabaseException */ public void writeConfig( PlatformConfig ob ) throws DatabaseException { String fn = xmldir + File.separator + PlatformConfigDir + File.separator + ob.makeFileName(); writeDatabaseObject(fn, new PlatformConfigParser(ob)); } /** * Deletes a platform configuration from the database. * This uses the object's configName member to uniquely identify * it in the database (not its ID number). * @param ob the object to delete */ public void deleteConfig( PlatformConfig ob ) throws DatabaseException { String fn = xmldir + File.separator + PlatformConfigDir + File.separator + ob.makeFileName(); tryDelete(fn); } /** * Read (or re-read) a single EquipmentModel from the database. * This uses the EquipmentModel's name (not it's ID number) to * uniquely identify the record in the database. * @param em object in which to store data * @throws DatabaseException */ public void readEquipmentModel( EquipmentModel em ) throws DatabaseException { String fn = ""; try { fn = makePath(EquipmentDir, em.makeFileName()); myParser.parse(new File(fn), em); } catch(Exception e) { throw new DatabaseException("Error reading '" + fn + "': " + e); } } /** * Write an EquipmentModel to the database. * This uses the EquipmentModel's name (not it's ID number) to * uniquely identify the record in the database. * @param ob object to write * @throws DatabaseException */ public void writeEquipmentModel( EquipmentModel ob ) throws DatabaseException { String fn = xmldir + File.separator + EquipmentDir + File.separator + ob.makeFileName(); writeDatabaseObject(fn, new EquipmentModelParser(ob)); } /** * Deletes an EquipmentModel object from the database. * @param ob the object to delete */ public void deleteEquipmentModel( EquipmentModel ob ) throws DatabaseException { String fn = xmldir + File.separator + EquipmentDir + File.separator + ob.makeFileName(); tryDelete(fn); } // public void readEquationSpec( EquationSpec ob ) // throws DatabaseException // { // String fn = ""; // try // { // fn = makePath(EquationDir, ob.makeFileName()); // myParser.parse(new File(fn), ob); // } // catch(Exception e) // { // throw new DatabaseException("Error reading '" + fn + "': " + e); // } // } // // // public void writeEquationSpec( EquationSpec ob ) // throws DatabaseException // { // String fn = xmldir + File.separator + EquationDir // + File.separator + ob.makeFileName(); // writeDatabaseObject(fn, new EquationSpecParser(ob)); // } // // public void deleteEquationSpec( EquationSpec ob ) // throws DatabaseException // { // String fn = xmldir + File.separator + EquationDir // + File.separator + ob.makeFileName(); // tryDelete(fn); // } /** * This reads the PresentationGroup object from the XML database, * using it's groupName to identify the record in the database. * @param ob object in which to store data */ public void readPresentationGroup( PresentationGroup ob ) throws DatabaseException { String fn = ""; try { fn = makePath(PresentationGroupDir, ob.makeFileName()); myParser.parse(new File(fn), ob); } catch(Exception e) { throw new DatabaseException("Error reading '" + fn + "': " + e); } } /** * Writes a presentation group and all of its DataPresentation elements * out to the database. * @param ob object to write */ public void writePresentationGroup( PresentationGroup ob ) throws DatabaseException { String fn = makePath(PresentationGroupDir, ob.makeFileName()); writeDatabaseObject(fn, new PresentationGroupParser(ob)); } /** * Deletes a presentation group and all of its DataPresentation elements * from the database. * @param ob the object to delete */ public void deletePresentationGroup( PresentationGroup ob ) throws DatabaseException { String fn = makePath(PresentationGroupDir, ob.makeFileName()); tryDelete(fn); } /** * Returns Date object representing the last modify time for this * presentation group in the database. * Returns null if the presentation group no longer exists in the database. * @param pg the PresentationGroup to check * @return last modify time as a Date object */ public Date getPresentationGroupLMT( PresentationGroup pg ) throws DatabaseException { String fn = makePath(PresentationGroupDir, pg.makeFileName()); File f = new File(fn); if (!f.exists()) { String msg = "Presentation Group '" + fn + "' has been deleted."; Logger.instance().log(Logger.E_WARNING, msg); return null; } return new Date(f.lastModified()); } /** * Reads a routing spec from the database. * @param ob object in which to store data */ public void readRoutingSpec( RoutingSpec ob ) throws DatabaseException { String fn = ""; try { fn = makePath(RoutingSpecDir, ob.makeFileName()); myParser.parse(new File(fn), ob); } catch(Exception e) { throw new DatabaseException("Error reading '" + fn + "': " + e); } } /** * Writes a routing spec to the database. * @param ob object to write */ public void writeRoutingSpec( RoutingSpec ob ) throws DatabaseException { String fn = makePath(RoutingSpecDir, ob.makeFileName()); writeDatabaseObject(fn, new RoutingSpecParser(ob)); } /** * Deletes a RoutingSpec from the database * @param ob the object to delete * @throws DatabaseException */ public void deleteRoutingSpec( RoutingSpec ob ) throws DatabaseException { String fn = makePath(RoutingSpecDir, ob.makeFileName()); tryDelete(fn); } /** * Returns Date object representing the last modify time for this * routing spec in the database. * Returns null if the routing spec no longer exists in the database. * @param rs the RoutingSpec to check * @return last-modify time as a Date object */ public Date getRoutingSpecLMT( RoutingSpec rs ) throws DatabaseException { String fn = makePath(RoutingSpecDir, rs.makeFileName()); File f = new File(fn); if (!f.exists()) { String msg = "Routing Spec '" + fn + "' has been deleted."; Logger.instance().log(Logger.E_WARNING, msg); return null; } return new Date(f.lastModified()); } /** * Reads (or re-reads) the DataSource object from the XML database. * This uses the argument's name member to identify the record in the * database. * @param ob object in which to store data */ public void readDataSource( DataSource ob ) throws DatabaseException { String fn = ""; try { fn = makePath(DataSourceDir, ob.makeFileName()); Logger.instance().log(Logger.E_DEBUG1, "XmlDatabaseIO: Reading DataSource '" + fn + "'"); myParser.parse(new File(fn), ob); } catch(Exception e) { throw new DatabaseException("Error reading '" + fn + "': " + e); } } /** * Writes a DataSource to the database. * @param ob object to write * @throws DatabaseException */ public void writeDataSource( DataSource ob ) throws DatabaseException { String fn = xmldir + File.separator + DataSourceDir + File.separator + ob.makeFileName(); writeDatabaseObject(fn, new DataSourceParser(ob)); } /** * Deletes a DataSource in the database. * @param ob the object to delete * @throws DatabaseException */ public void deleteDataSource( DataSource ob ) throws DatabaseException { String fn = xmldir + File.separator + DataSourceDir + File.separator + ob.makeFileName(); tryDelete(fn); } /** * Reads (or re-reads) a NetworkList from the database. This uses * the object's name member (not its ID) to uniquely identify the * record in the database. * @param ob object in which to store data */ public void readNetworkList( NetworkList ob ) throws DatabaseException { String fn = ""; try { fn = makePath(NetworkListDir, ob.makeFileName()); myParser.parse(new File(fn), ob); } catch(Exception e) { throw new DatabaseException("Error reading '" + fn + "': " + e); } } /** * Writes a NetworkList to the database. This uses * the object's name member (not its ID) to uniquely identify the * record in the database. * @param ob object to write * @throws DatabaseException */ public void writeNetworkList( NetworkList ob ) throws DatabaseException { String fn = makePath(NetworkListDir, ob.makeFileName()); writeDatabaseObject(fn, new NetworkListParser(ob)); } /** * Deletes a NetworkList from the database. * @param ob the object to delete * @throws DatabaseException */ public void deleteNetworkList( NetworkList ob ) throws DatabaseException { String fn = makePath(NetworkListDir, ob.makeFileName()); tryDelete(fn); } /** * Returns Date object representing the last modify time for this * network list in the database. * Returns null if the network list no longer exists in the database. * @param nl the NetworkList to check * @return Last modify time as a Date object */ public Date getNetworkListLMT( NetworkList nl ) throws DatabaseException { if (nl == NetworkList.dummy_all || nl == NetworkList.dummy_production) return this.getPlatformListLMT(); String fn = makePath(NetworkListDir, nl.makeFileName()); File f = new File(fn); if (!f.exists()) { String msg = "Network List '" + fn + "' has been deleted."; Logger.instance().log(Logger.E_WARNING, msg); return null; } return new Date(f.lastModified()); } /** * Writes EnumList to the database. * @param ob object to write */ public void writeEnumList( EnumList ob ) throws DatabaseException { String fn = xmldir + File.separator + EnumDir + File.separator + EnumListFile; writeDatabaseObject(fn, new EnumListParser(ob.getDatabase())); } /** * Local helper method to write objects & catch IO exceptions. * @param fn the file name * @param xow the XmlObjectWriter pre-configured. */ private void writeDatabaseObject( String fn, XmlObjectWriter xow ) throws DatabaseException { FileOutputStream os = null; if (!fn.endsWith(".xml")) fn = fn + ".xml"; try { Logger.instance().log(Logger.E_DEBUG1, "XmlDatabaseIO: Writing '" + fn + "'"); os = new FileOutputStream(new File(fn)); XmlOutputStream xos = new XmlOutputStream(os, xow.myName()); xos.xmlDtdUri = dtdUri; xos.writeXmlHeader(); xow.writeXml(xos); } catch(Exception e) { e.printStackTrace(); throw new DatabaseException("Error writing '" + fn + "': " + e); } finally { if (os != null) try { os.close(); } catch(Exception e){} } } /** * Convenience method to delete a file and handle exceptions. * @param fn the file name. * @throws DatabaseException if file cannot be deleted. */ private void tryDelete( String fn ) throws DatabaseException { if (!fn.endsWith(".xml")) fn = fn + ".xml"; File file = new File(fn); if (file.exists()) { try { Logger.instance().log(Logger.E_DEBUG1, "Deleting '" + fn + "' "); file.delete(); } catch (Exception e) { String err = "Cannot delete '" + fn + "': " + e; Logger.instance().log(Logger.E_FAILURE, err); throw new DatabaseException(err); } } else { Logger.instance().debug1( "Could not delete " + fn + ": file doesn't exist!"); } } /** * Returns counter to use to generate new Platform IDs. * @return Counter object */ public Counter getPlatformIdCounter( ) { if (platformIdCounter == null) { String fn = xmldir + File.separator + PlatformDir + File.separator + "PlatformIdCounter"; try { platformIdCounter = new FileCounter(fn); } catch(IOException e) { Logger.instance().log(Logger.E_FAILURE, "Cannot get platform ID file counter at '" + fn + "': "+e); } } return platformIdCounter; } public boolean commitAfterSelectStatus() { return(commitAfterSelect); } public void setCommitAfterSelect(boolean status) { commitAfterSelect=status; } @Override public LoadingAppDAI makeLoadingAppDAO() { return new XmlLoadingAppDAO(xmldir); } @Override public ScheduleEntryDAI makeScheduleEntryDAO() { return new XmlScheduleEntryDAO(this); } @Override public PlatformStatusDAI makePlatformStatusDAO() { return new XmlPlatformStatusDAO(this); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy