Using emf compare from code? - java

I have two emf models A and B where B only differs from A because it has an extra child node.
Now I would like to use emf compare from code to do:
1) Read model A and B and create model C which is a merged model from A and B. Basically this corresponds to A + the extra nodes from B.
I have looked at:
http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.emf/org.eclipse.emf.compare/examples/org.eclipse.emf.compare.examples.standalone/src/org/eclipse/emf/compare/examples/standalone/ExampleLauncher.java?view=co&root=Modeling_Project
But I don't see how I can compute the final merged model using the code:
DiffModel diff = CompareUtils.compare(model1, model2, Collections.<String, Object> emptyMap());
CompareUtils.merge(diff);
Any examples that shows how to compute the merged model??
I have now tried:
private void bob() {
ResourceSet resourceSet = new ResourceSetImpl();
Map extensionMap = (Map) resourceSet.getResourceFactoryRegistry()
.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
try {
Region region01 = StatemachineFactoryImpl.eINSTANCE.createRegion();
addResourceToModel(resourceSet, region01, "st1.xmi");
State state01 = StatemachineFactoryImpl.eINSTANCE.createState();
state01.setName("aaaa");
region01.getState().add(state01);
if (state01.eResource() == null) {
System.out.println("state01 NOT contained in resource!");
return;
}
Region region02 = StatemachineFactoryImpl.eINSTANCE.createRegion();
addResourceToModel(resourceSet, region02, "st2.xmi");
State state02 = StatemachineFactoryImpl.eINSTANCE.createState();
state02.setName("bbbb");
region02.getState().add(state02);
if (state02.eResource() == null) {
System.out.println("state02 NOT contained in resource!");
return;
}
final MatchModel match = MatchService.doMatch(region01, region02,
Collections.<String, Object> emptyMap());
final DiffModel diff = DiffService.doDiff(match, false);
final List<DiffElement> differences = new ArrayList<DiffElement>(
diff.getOwnedElements());
MergeService.merge(differences, true);
// Prints the results
addResourceToModel(resourceSet, match, "match.xmi");
addResourceToModel(resourceSet, diff, "diff.xmi");
if (match.eResource() != null)
System.out.println(ModelUtils.serialize(match)); // Throws an
// exception!
if (diff.eResource() != null)
System.out.println(ModelUtils.serialize(diff));
} catch (final InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void addResourceToModel(ResourceSet resourceSet, EObject obj,
String path) {
Resource res = resourceSet.createResource(URI.createURI(path));
res.getContents().add(obj);
}
But the line:
if (match.eResource() != null)
System.out.println(ModelUtils.serialize(match)); // Throws an
// exception!
even though match.eResource() != null
I get this error:
org.eclipse.emf.ecore.resource.Resource$IOWrappedException: The object 'statemachine.impl.StateImpl#11ce012 (name: bbbb)' is not contained in a resource.
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.endSave(XMLSaveImpl.java:306)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:235)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:254)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.save(XMLResourceImpl.java:229)
at org.eclipse.emf.compare.util.ModelUtils.serialize(ModelUtils.java:429)
I have added Region to a resource based on the documentation here:
http://wiki.eclipse.org/index.php/EMF-FAQ#I_get_a_DanglingHREFException:e.g..2C.22org.eclipse.emf.ecore.xmi.DanglingHREFException:_The_object_.27com.example.Foo.402f5dda_.28.29.27_is_not_contained_in_a_resource..22_What_do_I_need_to_do.3F
and the State is contained in the Region so I don't understand why I get the exception...any ideas?

Tul,
The stack trace you get means that one of the 'merged' objects is not contained into a resource : when merging, we copy an object that references a statemachine (which name is 'bbbb'), we then need to reference this state machine from the copied object ... and that statemachine we reference (is it copied or directly referenced from your other model? You should debug to see this) isn't itself contained in any resource.
State state02 = StatemachineFactoryImpl.eINSTANCE.createState();
state02.setName("bbbb");
region02.getState().add(state02);
if (state02.eResource() == null) {
System.out.println("state02 NOT contained in resource!");
return;
}
This should ensures that "bbbb" is indeed contained in a resource.
After this line :
MergeService.merge(differences, true);
Could you try to check once more if "state02.eResource() == null" ? If it is, then that is your issue. Otherwise, you'll have to make sure that this doesn't return :
for (State state : region01.getState()) {
if (state.eResource() == null) {
System.err.println(state.getName() + " is not contained in a resource);
return;
}
}

What about this?
Model1 targetModel = EcoreUtil.copy(model1);
addResourceToModel(targetModel) // assign the copied model to a resource
MatchModel match = MatchService.doMatch(targetModel, model2,
Collections.<String, Object> emptyMap());
DiffModel diff = DiffService.doDiff(match, false);
EList<DiffElement> differences = diff.getDifferences();
for (DiffElement diffElement : differences) {
MergeService.merge(diffElement, true);
}

Your exception:" org.eclipse.emf.ecore.resource.Resource$IOWrappedException: The object 'statemachine.impl.StateImpl#11ce012 (name: bbbb)' is not contained in a resource.". The StateImpl#11ce012 (name: bbbb) is in one resource named st2.xmi,but the match elememt is in another resource named "match.xml". The two resources are different and they do not refer each other. So the match element can NOT refer StateImpl. To solve this problem, all elements(state01, state02, match, diff) must be saved in ONE resource. The code is:
res.getContents().add(stat01);
res.getContents().add(stat02);
res.getContents().add(match);
res.getContents().add(diff);
By the way, the condition "state02.eResource() == null" is not nessary.

Related

How to go through HashMap and compare the object's data and replace the value for HashMap?

I am having a hard time writing a couple of lines of code. All my current codes are in: https://github.com/anabeen/MeetingJava
The problem that I have is, finding a suitable way to go through the hashmap and get the meetings that have overlapping times and replace them.
Map<LocalDate, Set<Meeting>> meetings = new HashMap<LocalDate, Set<Meeting>>();
Let's say we have a HashMap of
[{2011-03-21=[objectMeeting1, objectMeeting2]}]
and we need to add objectMeeting3 to that hashMap. How do I select the key "2011-03-21" to look at the objects in that hashmap and compare the set of objects in there with a new objectMeeting3's time (part of the data from object) and then replace that object?
In GitHub, I am trying to pass the MeetingSchedulerTest (). This is where I am stuck at:
Meeting meeting = extractMeeting(employeeId, requestLines[i],
officeStartTime, officeFinishTime, meetingSlotRequest1);
if(meetings.containsKey(meetingDate)){
// if the order overlaps
for (Map.Entry<LocalDate, Set<Meeting>> meetingEntry : meetings.entrySet()) {
if (meetingDate == meetingEntry.getKey())
{
Set<Meeting> setOfMeeting = meetingEntry.getValue();
for (Meeting m : setOfMeeting) {
}
}
}
// if the order doesn't
if (meetings.get(meetingDate) != null)
//shouldNotHaveOverlappingMeetings
{
System.out.println("HERES?");
meetings.remove(meetingDate);
Set<Meeting> meetingsForDay = new HashSet<Meeting>();
meetingsForDay.add(meeting);
meetings.put(meetingDate, meetingsForDay);
} else
{
System.out.println("HERES2?");
meetings.get(meetingDate).add(meeting);
}
}else if (meeting != null){
// if meeting doens't have meetingDate then create a new HashMap with date & Meeting
System.out.println("HERES3?");
Set<Meeting> meetingsForDay = new HashSet<Meeting>();
meetingsForDay.add(meeting);
meetings.put(meetingDate, meetingsForDay);
}
}
I figured out the answer by using this:
for (Map.Entry<LocalDate, Set<Meeting>> meetingEntry : meetings.entrySet()) {
if (meetingDate.equals(meetingEntry.getKey()))
{
System.out.println("HERES1? ");
Set<Meeting> setOfMeeting = meetingEntry.getValue();
for (Meeting m : setOfMeeting) {
System.out.println("comparing time? " + m.getStartTime().getHourOfDay() + " TO "
+ meeting.getStartTime().getHourOfDay());
if (m.compareTo(meeting) == 0) {
continue;
} else {
setToPut.add(m);
}
}
}
}

getting first level of categorisation from Notes view

I have a categorized Notes view, let say the first categorized column is TypeOfVehicle the second categorized column is Model and the third categorized column is Manufacturer.
I would like to collect only the values for the first category and return it as json object:
I am facing two problems:
- I can not read the value for the category, the column values are emptry and when I try to access the underlying document it is null
the script won't hop over to the category/sibling on the same level.
can someone explain me what am I doing wrong here?
private Object getFirstCategory() {
JsonJavaObject json = new JsonJavaObject();
try{
String server = null;
String filepath = null;
server = props.getProperty("server");
filepath = props.getProperty("filename");
Database db;
db = utils.getSession().getDatabase(server, filepath);
if (db.isOpen()) {
View vw = db.getView("transport");
if (null != vw) {
vw.setAutoUpdate(false);
ViewNavigator nav;
nav = vw.createViewNav();
JsonJavaArray arr = new JsonJavaArray();
Integer count = 0;
ViewEntry tmpentry;
ViewEntry entry = nav.getFirst();
while (null != entry) {
Vector<?> columnValues = entry.getColumnValues();
if(entry.isCategory()){
System.out.println("entry notesid = " + entry.getNoteID());
Document doc = entry.getDocument();
if(null != doc){
if (doc.hasItem("TypeOfVehicle ")){
System.out.println("category has not " + "TypeOfVehicle ");
}
else{
System.out.println("category IS " + doc.getItemValueString("TypeOfVehicle "));
}
} else{
System.out.println("doc is null");
}
JsonJavaObject row = new JsonJavaObject();
JsonJavaObject jo = new JsonJavaObject();
String TypeOfVehicle = String.valueOf(columnValues.get(0));
if (null != TypeOfVehicle ) {
if (!TypeOfVehicle .equals("")){
jo.put("TypeOfVehicle ", TypeOfVehicle );
} else{
jo.put("TypeOfVehicle ", "Not categorized");
}
} else {
jo.put("TypeOfVehicle ", "Not categorized");
}
row.put("request", jo);
arr.put(count, row);
count++;
tmpentry = nav.getNextSibling(entry);
entry.recycle();
entry = tmpentry;
} else{
//tmpentry = nav.getNextCategory();
//entry.recycle();
//entry = tmpentry;
}
}
json.put("data", arr);
vw.setAutoUpdate(true);
vw.recycle();
}
}
} catch (Exception e) {
OpenLogUtil.logErrorEx(e, JSFUtil.getXSPContext().getUrl().toString(), Level.SEVERE, null);
}
return json;
}
What you're doing wrong is trying to treat any single view entry as both a category and a document. A single view entry can only be one of a category, a document, or a total.
If you have an entry for which isCategory() returns true, then for the same entry:
isDocument() will return false.
getDocument() will return null.
getNoteID() will return an empty string.
If the only thing you need is top-level categories, then get the first entry from the navigator and iterate over entries using nav.getNextSibling(entry) as you're already doing, but:
Don't try to get documents, note ids, or fields.
Use entry.getColumnValues().get(0) to get the value of the first column for each category.
If the view contains any uncategorised documents, it's possible that entry.getColumnValues().get(0) might throw an exception, so you should also check that entry.getColumnValues().size() is at least 1 before trying to get a value.
If you need any extra data beyond just top-level categories, then note that subcategories and documents are children of their parent categories.
If an entry has a subcategory, nav.getChild(entry) will get the first subcategory of that entry.
If an entry has no subcategories, but is a category which contains documents, nav.getChild(entry) will get the first document in that category.

Call graphs in Soot

How do I use SOOT to build at Call graph? Or are there any better programs for this? I have been sent around the same five pages looking for answers and I can't find what I am looking for. There are also a problem with the plugin version to Eclipse. It is installed correct but I cant choose it when I want to run the code.
Small modification to previous answer
private static void visit(CallGraph cg, SootMethod method) {
String identifier = method.getSignature();
visited.put(method.getSignature(), true);
dot.drawNode(identifier);
// iterate over unvisited parents
Iterator<MethodOrMethodContext> ptargets = new Sources(cg.edgesInto(method));
if (ptargets != null) {
while (ptargets.hasNext()) {
SootMethod parent = (SootMethod) ptargets.next();
if (!visited.containsKey(parent.getSignature())) visit(cg, parent);
}
}
Here are some examples include call graph for Java. http://www.brics.dk/SootGuide/
And call graph for apk.
https://github.com/secure-software-engineering/soot-infoflow/issues/38
If you want to get the dot file, you can iterate over the callgraph and write the contents out in dot format like this.
private static void visit(CallGraph cg, SootMethod method) {
String identifier = method.getSignature();
visited.put(method.getSignature(), true);
dot.drawNode(identifier);
// iterate over unvisited parents
Iterator<MethodOrMethodContext> ptargets = new Targets(cg.edgesInto(method));
if (ptargets != null) {
while (ptargets.hasNext()) {
SootMethod parent = (SootMethod) ptargets.next();
if (!visited.containsKey(parent.getSignature())) visit(cg, parent);
}
}
// iterate over unvisited children
Iterator<MethodOrMethodContext> ctargets = new Targets(cg.edgesOutOf(method));
if (ctargets != null) {
while (ctargets.hasNext()) {
SootMethod child = (SootMethod) ctargets.next();
dot.drawEdge(identifier, child.getSignature());
System.out.println(method + " may call " + child);
if (!visited.containsKey(child.getSignature())) visit(cg, child);
}
}
}

How do you get the name of a git tag with the JGit API

I am familiar with using a tag reference to get a Ref and then start doing something:
Ref ref = repository.getRef("refs/tags/jena-2.11.2");
But if a ref is passed to me and I want to get the "refs/tags/jena-2.11.2" string back, how do I do it with the JGit API?
RevWalk walk = new RevWalk(repository);
RevObject object;
try {
object = walk.parseAny(ref.getObjectId());
} catch (MissingObjectException e) {
.....
} catch (IOException e) {
.....
}
if (object instanceof RevTag) {
// String tagName = object.what?????????
} else if (object instanceof RevCommit) {
...
} else {
...
}
A commit does not known about the labels that may point to it. Therefore there is no object.getRefs() or similar.
If you know that there should be a tag pointing to a given commit, you can use the ListTagCommand to obtain a list of all tags and then iterate over this list until you found the tag that points to this commit.
The NameRevCommand follows a more general approach. Like git name-rev, it finds symbolic names for a given commit.
Following your example, this snippet would print the tag name of the commit:
Map<ObjectId,String> names = git.nameRev().add( object ).addPrefix( "refs/tags/" ).call();
System.out( names.get( object ) );
The addPrefix ensures that tags take precedence over other refs in case that more than one ref points to object.

Test for null parameter in .properties file for MessageFormat

Is it possible, with resource bundles and MessageFormat to have the following result?
when I call getBundle("message.07", "test") to get "Group test"
when I call getBundle("message.07", null) to get "No group selected"
Every example I found on the Internet is with planets, with files on the disk and so on.
I only need to check if one parameter is null (or doesn't exist) in the resource bundle's properties file. I hope to find a special format for the null parameter something like {0,choice,null#No group selected|notnull#Group {0}}.
The method I use to get the bundles is:
public String getBundle(String key, Object... params) {
try {
String message = resourceBundle.getString(key);
if (params.length == 0) {
return message;
} else {
return MessageFormat.format(message, params);
}
} catch (Exception e) {
return "???";
}
}
I also call this method for other bundles, like
getBundle("message.08", 1, 2) => "Page 1 of 2" (always parameters, no need to check for null)
getBundle("message.09") => "Open file" (no parameters, no need to check for null)
What should I write in my .properties file for message.07 to have the result described?
What I have now is:
message.07=Group {0}
message.08=Page {0} of {1} # message with parameters where I always send them
message.09=Open file # message without parameters
I'll recommend not trying to change the bundle functionality (even if you have a getBundle method encapsulating it).
Simply do in your code:
getBundle(param == null? "message.07.null": "message.07", param)
Or make another method:
getBundleOrNull("message.07", param, "message.07.null")
that does
public String getBundleOrNull(String key, value, nullKey) {
return getBundle(value == null? nullKey: key: value);
}
Your .properties file,
message.07=Group {0}
message.08=Page {0} of {1}
message.09=Open file
message.null = No group selected
And then you need to change your code to put an explicit check params for null. And if null then you can do something like resourceBundle.getString(NULL_MSG). Where NULL_MSG will be this,
private static final String NULL_MSG = "message.null";
So, now your original method would become something like this.
public String getBundle(String key, Object... params) {
String message = null;
try {
if (params == null) {
message = resourceBundle.getString(NULL_MSG);
} else {
message = MessageFormat.format(resourceBundle.getString(key), params);
}
} catch (Exception e) {
e.printStackTrace();
}
return message;
}
Calling my method like below,
getBundle("message.07", "test") // returning 'Group test'
getBundle("message.07", null) // returning 'No group selected'
getBundle("message.08", 1, 2) // returning 'Page 1 of 2'
getBundle("message.08", null) // returning 'No group selected'
getBundle("message.09", new Object[0]) // returning 'Open file'
getBundle("message.09", null) // returning 'No group selected'
Now tell me where is the problem?

Categories

Resources