Skip to content

Commit

Permalink
Duplicate node id validation improved, class renamed. Stats command n…
Browse files Browse the repository at this point in the history
…ow returns counts sorted in decreasing order.
  • Loading branch information
michbarsinai committed Aug 15, 2017
1 parent b66d06c commit c0f0380
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 217 deletions.
101 changes: 51 additions & 50 deletions DataTagsLib/WORK/policy-models/dg-large-modular/questionnaire.dg
Original file line number Diff line number Diff line change
@@ -1,67 +1,68 @@
<*
DISCLAIMER:
NOT TO BE USED AS A LEGAL ADVICE
DISCLAIMER:
NOT TO BE USED AS A LEGAL ADVICE
*>
[#import ppra: ppra.dg ]
[#import medical: medical.dg ]
[#import ferpa: ferpa.dg ]
[#import dppa: dppa.dg ]
[#import gov: government-records.dg ]
[>global-start< ask:
{text: Do the data concern living persons?}
{text: Do the data concern living persons?}
{answers:
{yes:
[set: Code=green] <-- Explicit settings of colors is going away soon!
[>filter-medical< ask:
{text: Do the data contain health or medical information?}
{answers:
{yes: [call: medical>start]}}
]
[>filter-ppra< ask:
{text: Was the data collected from students in an elementary or secondary school?}
{answers:
{yes: [call: ppra>start]}
}
]
[>filter-ferpa< ask:
{text: Do the data contain any information derived from ministry of education data?}
{answers:
{yes: [call: ferpa>start]}
}]
[call: gov>Gov1]
[call: dppa>DPPA1]
[>futures< todo: Future additions go here.]}
[>filter-medical< ask:
{text: Do the data contain health or medical information?}
{answers:
{yes: [call: medical>start]}}
]
[>filter-ppra< ask:
{text: Was the data collected from students in an elementary or secondary school?}
{answers:
{yes: [call: ppra>start]}
}
]
[>filter-ferpa< ask:
{text: Do the data contain any information derived from ministry of education data?}
{answers:
{yes: [call: ferpa>start]}
}]
[call: gov>Gov1]
[call: dppa>DPPA1]
[>futures< todo: Future additions go here.]}
{no: [set: Code=blue; Identity=noPersonData] }
}]
[call: dua]
[end]
}]
[call: dua]
[end]

[>dua< section:
{title: Data Use Agreements}
[>dua-ext< todo: Data use agreements]
[>duaTimeLimit< ask:
{text: Is there any reason why we cannot store the data indefinitely? }
{answers:
{no: [set: TimeLimit=none] }
{yes:
[ask:
{text:For how long should we keep the data?}
{answers:
{ indefinitely: [set: TimeLimit=none] }
{ 50 years: [set: TimeLimit=_50yr] }
{ 5 years: [set: TimeLimit=_5yr] }
{ 2 years: [set: TimeLimit=_2yr] }
{ 1 year: [set: TimeLimit=_1yr] }
}]}}]
[>duaAdditional< ask:
{text: Did the data have any restrictions on sharing, e.g. stated in an agreement or policy statement?}
{answers:
{yes: [set: ContractOrPolicy=yes]}
{no: [set: ContractOrPolicy=no]}}
]
[>dua< section:
{title: Data Use Agreements}
[>dua-ext< todo: Data use agreements]
[>duaTimeLimit< ask:
{text: Is there any reason why we cannot store the data indefinitely? }
{answers:
{no: [set: TimeLimit=none] }
{yes:
[ask:
{text:For how long should we keep the data?}
{answers:
{ indefinitely: [set: TimeLimit=none] }
{ 50 years: [set: TimeLimit=_50yr] }
{ 5 years: [set: TimeLimit=_5yr] }
{ 2 years: [set: TimeLimit=_2yr] }
{ 1 year: [set: TimeLimit=_1yr] }
}]}}]
[>duaAdditional< ask:
{text: Did the data have any restrictions on sharing, e.g. stated in an agreement or policy statement?}
{answers:
{yes: [set: ContractOrPolicy=yes]}
{no: [set: ContractOrPolicy=no]}
}
]
]
[end]
<*
DISCLAIMER:
NOT TO BE USED AS A LEGAL ADVICE
DISCLAIMER:
NOT TO BE USED AS A LEGAL ADVICE
*>
6 changes: 6 additions & 0 deletions DataTagsLib/WORK/policy-models/import/cats.dg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[>iii< ask:
{text: Noname node #1 }
{answers:
{yes: [todo: todo in cats.dg]}
}
]
[>cat< section:
{title: Cats}
[>q-cats-group< ask:
Expand Down
6 changes: 6 additions & 0 deletions DataTagsLib/WORK/policy-models/import/dogs.dg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
[>WW< ask:
{text: Noname node #1 }
{answers:
{yes: [todo: first TODO in dogs.dg]}
}
]
[>dog< section:
{title: Dogs!}
[>q-dogType< ask:
Expand Down
5 changes: 2 additions & 3 deletions DataTagsLib/WORK/policy-models/import/graph.dg
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
[#import dogs: dogs.dg]
[#import cats: cats.dg]

[>q-order< ask:
{text: Do the dogs first?}
{answers:
{yes: [call: dogs>dog][call: cats>cat]}
{no: [call: cats>cat][call:dogs>dog]}
{yes: [call: dogs>dog]<*[call: cats>cat]*>}
{no: <*[call: cats>cat]*>[call:dogs>dog]}
}
]
[todo: specify mice]
Expand Down
2 changes: 1 addition & 1 deletion DataTagsLib/nbproject/private/configs/CLI-hello.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
application.args=policy-models/dg-large-modular
application.args=policy-models/import
work.dir=WORK
2 changes: 1 addition & 1 deletion DataTagsLib/nbproject/private/private.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ javadoc.preview=true
<<<<<<< HEAD
user.properties.file=/Users/michael/Library/Application Support/NetBeans/8.1/build.properties
=======
user.properties.file=C:\\Users\\user\\AppData\\Roaming\\NetBeans\\8.2\\build.properties
user.properties.file=/Users/michael/Library/Application Support/NetBeans/8.2/build.properties
>>>>>>> 3e85a56f4c480fd33c660bb30999ba6bf4a8e64b
10 changes: 1 addition & 9 deletions DataTagsLib/nbproject/private/private.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,7 @@
<file>file:/C:/Users/user/Desktop/DataTagging/DataTaggingLibrary%20-%20import/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/parser/decisiongraph/CompilationUnit.java</file>
</group>
<group name="DataTags">
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/model/graphs/DecisionGraph.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/model/types/AtomicSlot.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/test/edu/harvard/iq/datatags/runtime/ChartRunningTest.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/model/values/AtomicValue.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/parser/decisiongraph/CompilationUnit.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/parser/decisiongraph/DecisionGraphCompiler.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/model/values/AggregateValue.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/test/edu/harvard/iq/datatags/parser/decisiongraph/DecisionGraphParseResultTest.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/model/values/CompoundValue.java</file>
<file>file:/Users/michael/Documents/PhD/IQSS/Data-Tags/DataTaggingLibrary/DataTagsLib/src/edu/harvard/iq/datatags/tools/processors/EndNodeOptimizer.java</file>
</group>
</open-files>
</project-private>
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ public void execute(CliRunner rnr, List<String> args) throws Exception {
rnr.getModel().getDecisionGraph().nodes().forEach(
nd -> countsByClass.computeIfAbsent(nd.getClass(), c -> new AtomicInteger(0)).incrementAndGet() );

final Map<String, Integer> counts = new HashMap<>();
countsByClass.entrySet().forEach( ent -> {
String className = C.last(ent.getKey().getName().split("\\."));
rnr.println( " %s\t%d", className, ent.getValue().intValue() );
counts.put(className, ent.getValue().intValue());
});

counts.entrySet().stream().sorted((e1,e2)->e2.getValue().compareTo(e1.getValue()))
.forEach( ent -> rnr.println(" %s\t%d", ent.getKey(), ent.getValue()));
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstNode;
import edu.harvard.iq.datatags.tools.DecisionGraphAstValidator;
import edu.harvard.iq.datatags.tools.NodeValidationMessage;
import edu.harvard.iq.datatags.tools.RepeatIdValidator;
import edu.harvard.iq.datatags.tools.DuplicateIdValidator;
import edu.harvard.iq.datatags.tools.UnreachableNodeValidator;
import edu.harvard.iq.datatags.tools.ValidationMessage;
import edu.harvard.iq.datatags.visualizers.graphviz.GraphvizGraphNodeAstVisualizer;
Expand Down Expand Up @@ -66,7 +66,7 @@ public static void main(String[] args) {
System.out.println("===============");

System.out.println("Validating repeating ids");
RepeatIdValidator riv = new RepeatIdValidator();
DuplicateIdValidator riv = new DuplicateIdValidator();
List<ValidationMessage> repeatIdMessages = riv.validate(refs);
if (repeatIdMessages.size() > 0) {
System.out.println(repeatIdMessages);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import edu.harvard.iq.datatags.tools.DecisionGraphAstValidator;
import edu.harvard.iq.datatags.tools.DecisionGraphValidator;
import edu.harvard.iq.datatags.tools.DuplicateNodeAnswerValidator;
import edu.harvard.iq.datatags.tools.RepeatIdValidator;
import edu.harvard.iq.datatags.tools.DuplicateIdValidator;
import edu.harvard.iq.datatags.tools.UnreachableNodeValidator;
import edu.harvard.iq.datatags.tools.ValidationMessage;
import edu.harvard.iq.datatags.tools.processors.YesNoAnswersSorter;
Expand All @@ -32,7 +32,7 @@
* Loads policy models from {@link PolicyModelData}. Each loader has a list of
* validators and post-processors that is runs in the appropriate places.
*
* Use the class' statis methods to obtain instances that fit certain contexts
* Use the class' static methods to obtain instances that fit certain contexts
* (e.g. dev, production).
*
* @author michael
Expand All @@ -50,7 +50,7 @@ public static PolicyModelLoader verboseLoader() {
PolicyModelLoader res = new PolicyModelLoader();

res.add( new DuplicateNodeAnswerValidator() );
res.add( new RepeatIdValidator() );
res.add(new DuplicateIdValidator() );

res.add( new UnreachableNodeValidator() );

Expand All @@ -64,7 +64,7 @@ public static PolicyModelLoader productionLoader() {
PolicyModelLoader res = new PolicyModelLoader();

res.add( new DuplicateNodeAnswerValidator() );
res.add( new RepeatIdValidator() );
res.add(new DuplicateIdValidator() );


res.add( new EndNodeOptimizer() );
Expand Down Expand Up @@ -124,22 +124,23 @@ public PolicyModelLoadResult load( PolicyModelData data ) {
}
model.setDecisionGraph(dg);

// Load localizations
Path localizations;
try {
localizations = ciResolve(data.getMetadataFile().getParent(), LocalizationLoader.LOCALIZATION_DIRECTORY_NAME);
if ( localizations != null ) {
Files.list(localizations).filter(Files::isDirectory)
.map(p->p.getFileName().toString())
.forEach(res.getModel()::addLocalization);
}
} catch (IOException ex) {
res.addMessage( new ValidationMessage(Level.WARNING, "IO Error reading localizations: " + ex.getMessage()));
}

} else {
res.addMessage( new ValidationMessage(Level.ERROR, "Failed to create decision graph; see previous errors.") );
}

// Load localizations
Path localizations;
try {
localizations = ciResolve(data.getMetadataFile().getParent(), LocalizationLoader.LOCALIZATION_DIRECTORY_NAME);
if ( localizations != null ) {
Files.list(localizations).filter(Files::isDirectory)
.map(p->p.getFileName().toString())
.forEach(res.getModel()::addLocalization);
}
} catch (IOException ex) {
res.addMessage( new ValidationMessage(Level.WARNING, "IO Error reading localizations: " + ex.getMessage()));
}

} catch (NoSuchFileException ex) {
res.addMessage( new ValidationMessage(Level.ERROR, "File " + ex.getMessage() + " cannot be found."));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package edu.harvard.iq.datatags.tools;

import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstAnswerSubNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstAskNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstCallNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstConsiderAnswerSubNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstConsiderNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstEndNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstNode.NullVisitor;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstRejectNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstSectionNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstSetNode;
import edu.harvard.iq.datatags.parser.decisiongraph.ast.AstTodoNode;
import edu.harvard.iq.datatags.runtime.exceptions.DataTagsRuntimeException;
import edu.harvard.iq.datatags.tools.ValidationMessage.Level;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.util.stream.Collectors.toList;

/**
* Checks that every id in the questionnaire is unique. Returns an ERROR with
* each repeated node id.
*
* @author Naomi
* @author Michael
*/
public class DuplicateIdValidator extends NullVisitor implements DecisionGraphAstValidator {

private final Map<String, List<AstNode>> nodesById = new HashMap<>();

@Override
public List<ValidationMessage> validate(List<? extends AstNode> refs) {
nodesById.clear();

refs.stream().forEach(ref -> ref.accept(this));

return nodesById.entrySet().stream().filter( ent -> ent.getValue().size()>1 )
.map( ent -> new ValidationMessage(Level.ERROR,
String.format("Duplicate node id: '%s' (nodes: %s)", ent.getKey(), ent.getValue())) )
.collect( toList() );

}

@Override
public void visitImpl(AstConsiderNode nd) throws DataTagsRuntimeException {
collect(nd);
for (AstConsiderAnswerSubNode ansRef : nd.getAnswers()) {
for (AstNode node : ansRef.getSubGraph()) {
node.accept(this);
}
}
}

@Override
public void visitImpl(AstAskNode nd) throws DataTagsRuntimeException {
collect(nd);
for (AstAnswerSubNode ansRef : nd.getAnswers()) {
for (AstNode node : ansRef.getSubGraph()) {
node.accept(this);
}
}
}

@Override
public void visitImpl(AstSetNode nd) throws DataTagsRuntimeException {
collect(nd);
}

@Override
public void visitImpl(AstRejectNode nd) throws DataTagsRuntimeException {
collect(nd);
}

@Override
public void visitImpl(AstCallNode nd) throws DataTagsRuntimeException {
collect(nd);
}

@Override
public void visitImpl(AstTodoNode nd) throws DataTagsRuntimeException {
collect(nd);
}

@Override
public void visitImpl(AstEndNode nd) throws DataTagsRuntimeException {
collect(nd);
}

@Override
public void visitImpl(AstSectionNode nd) throws DataTagsRuntimeException {
collect(nd);
}

private void collect( AstNode nd ) {
nodesById.computeIfAbsent(nd.getId(), str -> new ArrayList<>(1)).add(nd);
}

}
Loading

0 comments on commit c0f0380

Please sign in to comment.