We have a large project and I am using Enterprise Architect version 10 to reverse engineer a small package within the project into UML for the purposes of refactoring. I want to only include elements that will be contained within the diagrams I am going to create (I know this is stupid, but we can't have 1 model to rule them all).
I would like to reverse all the source and then delete all elements that do not end up on my diagrams. Is there a way to do this? I know that I can find any given element in the diagrams from the GUI, so would there at least be a way to script this?
The alternative is to manually pick all dependencies and reverse only those files, which I may end up doing.
Thanks
EA comes with a built-in search called "Find Orphans". This will list all elements that do not appear on a diagram. You can run this search (Ctrl+Alt+A, select "Diagram Searches" from the first list box and "Find Orphans" from the second list box and click Run), select all the results (Ctrl+A) and delete all (Ctrl+Del). However, this is at your own risk - there is nothing wrong with an element being in the model but not on any diagrams.
Yes, you can script this. It will be a little involved, but it can be done.
There's no immediate API support to find what you're looking for so you'll need to go into the database to find all elements that are not shown in any diagrams. Once you've done that, you can delete each such element from its containing package.
Elements are stored in t_object and diagram objects (the graphical representation of one element in one diagram) in t_diagramobjects. An entry in t_diagramobjects has a reference to the diagram (Diagram_ID) and to the element being displayed (Object_ID).
(If you're new to EA hacking, yes, they're called Elements in the API and Objects in the database. Just a fact of life.)
So:
Find all t_object.Object_ID which do not occur in t_diagramobjects.Object_ID.
Loop through this set and, using Repository.GetElementByID(), retrieve each Element.
Fetch the element's containing package using Repository.GetPackageByID(element.PackageID).
Spin through the package's Elements collection using GetAt() in a for loop, find the Element whose ElementID matches the one you're after and Delete() it. Don't forget to Refresh() the collection afterwards.
There is a method Repository.SQLQuery(), which allows you to perform a select query against the database, but you have to parse the result from a single XML string.
It's simpler to use Repository.GetElementsByQuery(), which returns the elements in a Collection, but this requires you to predefine the query as an EA search. If you use this, you can skip steps 1 and 2 above.
Of course, you could go straight into the database and simply delete all those t_object rows which are not referred to from t_diagramobjects. This is a terribly bad idea which will (I'm pretty sure) leave you with a corrupted database. When you use the API to delete things, EA cleans up all references (so no connectors are left dangling, etc).
And of course, you should only unleash a script like this if you are absolutely sure there are no other elements that aren't shown in diagrams that need to be kept. So a temp project for this is probably a good idea.
Note, finally, that packages are also elements, and if you don't want to lose all your imported source in one fell swoop by deleting the package they're in (because the package itself is typically not shown in a diagram, is it?) you should probably exclude t_object.Object_Type / Element.Type "Package".
I know this is old but I think I have something to contribute :)
The simplest answer has already been given and it is the "Find Orphans" thingy. Now while cleaning a big EA repository I inherited I noticed there are cases where a given object may not be in a diagram but a child object will. In this case you don't want to be cleaning the parent object or you may lose the child.
So I crafted the following search:
select
o.ea_guid as CLASSGUID, o.object_type as CLASSTYPE, *
from
t_object o
where
o.Object_Type != 'Package'
and
not exists (select t_diagramobjects.Diagram_ID from t_diagramobjects where t_diagramobjects.Object_ID = o.object_ID)
and
not exists (select t2.OBJECT_ID from t_object t2 where t2.PARENTID=o.OBJECT_ID)
It will only return "orphans that don't have a parent". Of course it could be improved to only return "orphans that don't have a parent that is itself an orphan" but I did not need that and could do some manual work...
(you access the SQL Search interface by Control+F/Builder/SQL)
The user interface in Enterprise Architect version 12 appears to have changed slightly for finding orphaned elements.
Ctrl + F to "Find in Project".
Select "Diagram Searches" from the Search Category drop down.
Select "Find Orphans" from the Search drop down.
Leave blank to find all orphans.
Click Run or press Enter.
Related
I am a bit confused how to use the component <sw-entity-multi-select>. I understand that the difference between this component and the <sw-entity-multi-id-select> is that the first one returns the entities and the latter one returns just the id of the selected entities. But from the structure and the props they are totally different.
I am confused, because I mainly use the component as this:
<sw-entity-multi-select
entityName="language"
:entity-collection="languages"
:criteria="salesChannelLanguageCriteria"
:label="Language"
#change="selectLanguage"
>
</sw-entity-multi-select>
I could remove the entityName here, as the name is retrieved from the collection as well. But when I dig into the core, I see that inside selectLanguage I should do this:
selectLanguage(languages) {
this.languageIds = languages.getIds();
this.languages = languages;
}
I now understand that languageIds are kind of the v-model that determine, which entities should be selected in the component. Is this true? Why do I have to set the this.languages here again then? To me it's kind of magic if languageIds have this role here, because it's not referenced anywhere on the component. How does it work and how do I tell the component which items are selected - is using languageIds the correct way?
I now understand that languageIds are kind of the v-model that determine, which entities should be selected in the component. Is this true?
No. This example probably just extracts the IDs for some other use, e.g. for adding associations of language to another entity. One could arguably that if this is the only purpose of the selection sw-entity-multi-id-select might be the better component to use.
Why do I have to set the this.languages here again then?
Because you want to store the updated entity collection to persist the selection. Whatever is selected within the multi select is derived from that collection. So, let's say, initially you start out with an empty entity collection. You select some entities and the change is emitted with the updated collection containing the selected entities. Given we have :entity-collection="languages" we then want this.languages to be this updated collection, so the selection persists. So we kinda complete a loop here.
On another note, you could also use the collection with v-model="languages". In that case any additions or removals within the selection would be applied reactively to the collection and you wouldn't need to set this.languages after each change and you could also remove :entity-collection="languages". So basically, which of these approaches you use depends on whether you want your changes applied reactively or not.
I am generating a short list of 10 to 20 strings which I want to lookup on dbpedia to see if they have an organization tag and if so return the industry/sector tag. I have been looking at the SPARQLwrapper queries on their website but am having trouble constructing one that returns organization and sector/industry for my string. Is there a way to do this?
If I use the code below I get a list of industry types I think rather than the industry of the company.
from SPARQLWrapper import SPARQLWrapper, JSON
sparql = SPARQLWrapper("http://dbpedia.org/sparql")
sparql.setQuery("""
SELECT ?industry WHERE
{ <http://dbpedia.org/resource/IBM> a ?industry}
""")
sparql.setReturnFormat(JSON)
results = sparql.query().convert()
Instead of looking at queries which are meant to help you understand the querying tool, you should start by looking at the data which is being queried. For instance, just click http://dbpedia.org/resource/IBM, and look at the properties (the left hand column) to see its rdf:type values (of which there are MANY)!
Note that IBM is not described as a ?industry. IBM is described as a <http://dbpedia.org/resource/Public_company> (among other things). On the other hand, IBM is also described as having three values for <http://dbpedia.org/ontology/industry> --
<http://dbpedia.org/resource/Cloud_computing>
<http://dbpedia.org/resource/Information_technology>
<http://dbpedia.org/resource/Cognitive_computing>
I don't know whether these are what you're actually looking for or not, but hopefully what I've done above will start you down the right path to whatever you do want to get out of DBpedia.
I have a list of approx 10K entries (and growing) I need to be able to reference in an xPages app. I have had lookup limitations using #DbLookup, so have looked at other options. Unfortunately I continue to run into these limitations.
I am currently loading the lookup list into a session scope variable on page load (which has performance impacts), and the reference the scoped variable for the combo box.
I am using the following simple process to load the list for the combo box. This, however, is also running into limitations.
var lookupView:NotesView = database.getView("LookupView");
sessionScope.lookupList = lookupView.getColumnValues(0) + "|" + lookupView.getColumnValues(4);
I would like a method to perform a lookup that can handle the larger list (main priority) with performance being number 2. The page is used by a limited number of users with the function being most important.
Take a look at this code snippet "Pure Java version of DbLookup & DbColumn, with cache, sort and unique" and either use it directly or use it as inspiration.
You should consider storing the list in application scope since it seems that the list is the same for all users. This means that you need to change the code in the code snippet to use applicationScope instead of sessionScope.
I doubt your users want or need to pick some value from combo with 10k+ lines.
Rethink your approach, you can use autocomplete feature with dynamic filter/search in live view (no scoped variable needed), as pointed by Mark. Another approach is to divide that values into some groups and split that combo to two or three with cascading choose/lookup function. First one picks one group, second one looks up only options from first group. That way you probably won't hit that #DbLookup limitations.
here's a really quick question...
Is there a type of Sitecore Editor control that I can use in the Template Builder to enable the product owners to add a free collection of strings in the CMS Editor?
I know that I can add a simple data object that has a single string field, add a number of these data objects and then add a Multilist to the Editor with that group of data objects as the Source, but that would mean that the product owners would have to add all of their strings as these data objects and then select them from the Multilist.
I'm trying to make it simpler for them, but I can't seem to find a Sitecore Editor control that enables them to enter a collection of strings directly in the Editor... is there one?
The short answer is no, there is no way to do this in Sitecore.
All hope is not lost, however. You can always create your own field type for something like this, but doing so does require a significant level of effort.
I have core data app with an entity OBSERVATION that has as one of its attributes DEALNAME.
I want to reference through Interface Builder or by making custom modifications to an NSArrayController a list of unique sorted dealnames so that I can use them in a pop-up.
I have attempted to use #distinctUnionOfSets (and #distinctUnionOfArrays) but am unable to locate the proper key sequence.
I can sort the ArrayController by providing a sort descriptor, but do not know how to eliminate duplicates.
Are the #distinct... keys the right methodology? It would seem to provide the easiest way to optimize the use of IB.
Is there a predicate form for removing duplicates?
Or do I need to use my custom controller to extract an NSSet of the specific dealnames, put them back in an array and sort it and reference the custom array from IB?
Any help would be appreciated. I am astounded that other have not tried to create a sorted-unique pop-up in tableviews.
You need to take a look at -[NSFetchRequest returnsDistinctResults]. That is the level you need to be handling the uniquing of data.
Although I do not have a definitive answer for you, I think there are two ways you can go about it.
The way you already started. You need to bind the contents array of the PopUp button, not just against the arrayController.arrangedObjects, but continue on the path and somehow filter only objects with distinct "DealName"s. This means - the arrayController presents ALL the entities (and may sort them for you) but the PopUp button will have its contents filter via some sophisticated binding to the array controller.
Make your filtering at the ArrayController level (as suggested in another answer here). Here it depends how you set up the array controller. If It is set up to use an "Entity" (vs. "Class") which means the array controller will fetch CoreData entities directly - you can modify its "Fetch" to only bring a subset of the "OBSERVATION" entities with distinct values of "DEALNAME". I don't know how to control WHICH entities are filtered out in this case. Otherwise, you can setup the arrayController to work with "Class" objects, and then you can fetch the entities yourself (in code) and populate the arrayController programmatically, with just the entities you like.
In the second option, the Popup button should be bound normally to the arrayController's arrangedObjects.