package votorola.a.trust; // Copyright 2010, 2012, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import java.io.*; import votorola.a.*; import votorola.g.io.*; import votorola.g.lang.*; /** A completed trace of a neigbourhood trust network, which also serves as a residential * voter register and (till we start aggregating multiple registers) a simple voter list. * To query for a registrant's membership in electoral districts and other * divisions:

     Set divisionSet = trace.membershipTable().divisionSet(
  *       registrant.email() );
* *

Other registration properties are lumped together in a single trace node, one per * registrant. To obtain the registrant's trace node:

     TraceNode traceNode = trace.traceNodeTable().getOrCreate( registrant );
* *

Most of the registration properties are set by intermediation of the local * administrator's votrace.js script.

* * @see Working example of votrace.js */ public @ThreadSafe final class NetworkTrace implements Serializable { // cf. a/count/Count. NetworkTrace is currently superflous, as we have no meta-data to // model. private static final long serialVersionUID = 2L; // depends not only on structure of this class, but also structure of relational tables /** Partially constructs a NetworkTrace. * * @see #init(Membership.Table,TraceNodeW.Table) */ NetworkTrace( ReadyDirectory _readyDirectory ) { readyDirectory = _readyDirectory; } /** Completes the construction of a new VoterList. */ @ThreadRestricted("constructor") void init( Membership.Table _membershipTable, TraceNodeW.Table _traceNodeTable ) { membershipTable = _membershipTable; traceNodeTable = _traceNodeTable; } // ```````````````````````````````````````````````````````````````````````````````````` /** Returns true if this trace is probably in sync with the serial file of the * specified ready directory; false if that file has since been modified or deleted. * Always returns false if the trace was never originally deserialized from that * file path. * * @see #readObjectFromSerialFile(ReadyDirectory) */ boolean isObjectReadFromSerialFile( final ReadyDirectory newReadyDirectory ) { if( readObjectFromSerialFile_modTime == 0L || !readyDirectory.equals( newReadyDirectory )) return false; final File serialFile = readyDirectory.newTraceSerialFile(); return readObjectFromSerialFile_modTime == serialFile.lastModified(); // 0L if file does not exist } public static NetworkTrace readObjectFromSerialFile( final ReadyDirectory readyDirectory ) { final File serialFile = readyDirectory.newTraceSerialFile(); final NetworkTrace t = new NetworkTrace( readyDirectory ); t.readObjectFromSerialFile_modTime = serialFile.lastModified(); return t; } private long readObjectFromSerialFile_modTime; // final after readObjectFromSerialFile final void writeObjectToSerialFile() throws IOException { final File serialFile = readyDirectory.newTraceSerialFile(); FileX.ensuredirs( serialFile.getParentFile() ); FileX.writeObject( NetworkTrace.this, serialFile ); } // ------------------------------------------------------------------------------------ /** The relational store of memberships that (in part) backs this trace, if known. It * is a table named "{@linkplain Membership.Table#SCHEMA_NAME * SCHEMA_NAME}.YYYY-MD-S-membership-S", stored in the output * database. * * @return reference to relational store; or null, if the trace was not * initialized with a reference * * @see votorola.a.VoteServer.Run#database() * @see #init(Membership.Table,TraceNodeW.Table) */ public Membership.Table membershipTable() { return membershipTable; } private transient Membership.Table membershipTable; // final after init /** The relational store of trace nodes that (in part) backs this trace, if known. It * is a table named "{@linkplain TraceNodeW.Table#SCHEMA_NAME * SCHEMA_NAME}.YYYY-MD-S-trace_node-S", stored in the output * database. * * @return reference to relational store; or null, if the trace was not * initialized with a reference * * @see votorola.a.VoteServer.Run#database() * @see #init(Membership.Table,TraceNodeW.Table) */ public TraceNodeW.Table traceNodeTable() { return traceNodeTable; } private transient TraceNodeW.Table traceNodeTable; // final after init /** The file part of the backing for this trace. */ public ReadyDirectory readyDirectory() { return readyDirectory; } private transient ReadyDirectory readyDirectory; // final after init // ==================================================================================== /** API for all traces of trust networks within the scope of a vote-server. * * @see VoteServer#scopeTrace() */ public static @ThreadSafe final class VoteServerScope { /** Constructs a VoteServerScope. */ public @Warning( "non-API" ) VoteServerScope( final VoteServer vS ) { final String loc = "votrace" + File.separator; readyToReportLink = new File( vS.outDirectory(), loc + "_readyTrace_report" ); snapToReportLink = new File( vS.outDirectory(), loc + "_snap_report" ); } // -------------------------------------------------------------------------------- /** The path of the _readyTrace_report symbolic link. When this link * exists, it points to the ready directory of the currently reported trace. * * @return abstract path (never null) of symbolic link. * * @see votrace */ public File readyToReportLink() { return readyToReportLink; } private final File readyToReportLink; /** The path of the _snap_report symbolic link. When this link * exists, it points to the snap directory of the currently reported trace. This * is for informational and external use only, all code should instead use * {@linkplain #readyToReportLink() readyToReportLink}. * * @return abstract path (never null) of symbolic link. */ public File snapToReportLink() { return snapToReportLink; } private final File snapToReportLink; } }