public class PeriodicScheduleNatureImpl extends BaseScheduleNatureImpl implements PeriodicScheduleNature { public static final @NonNull String NAME = "org.allmyinfo.schedule.periodic"; @SuppressWarnings("unused") private static final @NonNull Logger LOGGER = Logger.getLogger(PeriodicScheduleNatureImpl.class); private final @NonNull ScheduleNatureImpl scheduleNature; private final PeriodMeaning.@NonNull Reactor pmReactor; private final @NonNull OffsetToPeriodicScheduleAssignmentNatureImpl otpsan; PeriodicScheduleNatureImpl( final @NonNull NodeId nodeId, final AnonymousSecurityUser.@NonNull Reactor asuReactor, final Coordinator.@NonNull Reactor coordReactor, // final SystemContextProvider.@NonNull Reactor scpReactor, final OwnerMeaning.@NonNull Reactor omReactor, final @NonNull ScheduleNatureImpl scheduleNature, final PeriodMeaning.@NonNull Reactor pmReactor, final @NonNull OffsetToPeriodicScheduleAssignmentNatureImpl otpsan, final @NonNull RowIdsNodeKeyType rinkt) { super(nodeId, asuReactor, coordReactor, scpReactor, omReactor, rinkt); this.scheduleNature = scheduleNature; this.pmReactor = pmReactor; this.otpsan = otpsan; } @Override public @NonNull Set<Nature> getSuperNatures() { final Set<Nature> set = super.getSuperNatures(); set.add(scheduleNature); return set; } @Override protected @NonNull Set<NodeId> getRequiredMeanings() { final Set<NodeId> set = super.getRequiredMeanings(); set.add(pmReactor.getInstance().getNodeId()); return set; } @Override public @NonNull Schedule getSchedule( @NonNull final NodesTransaction txn, @NonNull final NodeId nodeId) { return getPeriodicSchedule(txn, nodeId); } @Override public @NonNull PeriodicSchedule getPeriodicSchedule( @NonNull final NodesTransaction txn, @NonNull final NodeId nodeId) { final PeriodMeaning pm = pmReactor.getInstance(); final Period period = pm.getPeriod(txn, nodeId); if (period == null) throw new NullPointerException("period"); final @NonNull Set<@NonNull Long> offsets = otpsan.getOffsets(txn, nodeId); return new PeriodicScheduleImpl(period, offsets); } }
public static class SAXHandler extends DefaultHandler { private static final Logger LOGGER1 = Logger.getLogger(SAXHandler.class); private final @NonNull List<Canceller> cancellers = new LinkedList<Canceller>(); private final @NonNull NodesTransaction txn; private final @NonNull NamedNodeIdType nnit; private final @NonNull Int2NodeIdType i2nit; private final @NonNull ParentMeaning parentMeaning; private Level level = new Level(null); public SAXHandler( final @NonNull NodesTransaction txn, final @NonNull NamedNodeIdType nnit, final @NonNull Int2NodeIdType i2nit, final @NonNull ParentMeaning parentMeaning) { this.txn = txn; this.nnit = nnit; this.i2nit = i2nit; this.parentMeaning = parentMeaning; } public void add(final Canceller canceller) { if (canceller != null) cancellers.add(canceller); } @Override public void warning(final SAXParseException e) { SAXHandler.LOGGER1.warn("Received warning notification from SAX parser", e); } @Override public void error(final SAXParseException e) { SAXHandler.LOGGER1.error("Received error notification from SAX parser", e); } @Override public void fatalError(final SAXParseException e) { SAXHandler.LOGGER1.error("Received fatal error notification from SAX parser", e); } @Override public void characters(final char[] ch, final int start, final int length) { level.sb.append(ch, start, length); } @Override public void startDocument() {} @Override public void endDocument() {} @Override public void startElement( final String uriString, final String localName, final String qName, final Attributes saxAttrs) throws SAXException { checkCancelled(); final Level parentLevel = level; level = new Level(parentLevel); // uriString + localName = global meaning // if no uriString then localName = meaning to parent final NodeId meaningNodeId = constructMeaningNodeId(parentLevel, uriString, localName); // link through an intermediate node in case there are duplicates NodeId targetNodeId = txn.getTarget(parentLevel.nodeId, meaningNodeId); if (targetNodeId == null) { targetNodeId = i2nit.create(parentLevel.nodeId, parentLevel.index++); txn.insertLink(parentLevel.nodeId, targetNodeId, meaningNodeId, false); } txn.insertLink(level.nodeId, targetNodeId, parentMeaning.getNodeId(), false); // create nodes for attributes for (int i = 0; i < saxAttrs.getLength(); i++) { final String attrLocalName = saxAttrs.getLocalName(i); final String attrUriString = saxAttrs.getURI(i); final String attrValue = saxAttrs.getValue(i); if (attrValue != null) { final NodeId attrNodeId = txn.insertNode(new StringDatum(attrValue)); final NodeId attrMeaningNodeId = constructMeaningNodeId(level, attrUriString, attrLocalName); // TODO what if an attribute name collides with an element name? txn.insertLink(level.nodeId, attrNodeId, attrMeaningNodeId, false); txn.dereference(attrNodeId); } } } @Override public void endElement(final String uriString, final String localName, final String qName) { // save text, if any if (level.sb.length() > 0) { final String string = level.sb.toString(); if (string != null) txn.updateNode(level.nodeId, new StringDatum(string)); } level = level.parent; } @Override public void startPrefixMapping(final String prefix, final String uriString) {} @Override public void endPrefixMapping(final String prefix) {} private final void checkCancelled() throws CancelledException { for (final Canceller canceller : cancellers) if (canceller.wasCancelled()) throw new CancelledException(); } private @NonNull NodeId constructMeaningNodeId( final Level parentLevel, final String uriString, final String localName) { NodeId meaningNodeId; if (localName != null) { if (uriString != null) { // create a meaning relative to the namespace URI final NodeId namespaceNodeId = nnit.create(null, uriString); meaningNodeId = nnit.create(namespaceNodeId, localName); } else { // uriString is null, create a meaning relative to the parent meaningNodeId = nnit.create(parentLevel.nodeId, localName); } } else { // localName is null, create an indexed meaning relative to the parent meaningNodeId = i2nit.create(parentLevel.nodeId, parentLevel.index++); } return meaningNodeId; } }