Eclipse UML2: obtain value of a property defined in a profile - eclipse

I'm new to eclipse UML2 and get stuck in the following problem.
I defined a profile with two stereotypes: ServiceRequest and TransitionEdge. ServiceRequest extends the Action metaclass with two additional properties (cpu, memory), and TransitionEdge extends the ActivityEdge metaclass with the additional property called "probability". All these properties are of type float defined as a PrimitiveType.
The I created an activity diagram that have the profile and stereotypes applied. In the activity diagram, each edge is a TransitionEdge defined in the profile, and a value has been assigned to the probability property.
Having the profile and the activity model, I use the following Java code to load them.
// Load the profile
URI profileUri = URI.createURI(PROFILE_NAME);
ResourceSet profileSet = new ResourceSetImpl();
profileSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
profileSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
profileSet.createResource(profileUri);
Resource profileResource = profileSet.getResource(profileUri, true);
Profile profile = (Profile)EcoreUtil.getObjectByType(profileResource.getContents(), UMLPackage.Literals.PROFILE);
Profile sopraProfile = (Profile)profile.getOwnedMember(PROFILE_NAME);
Stereotype serviceRequestStereotype = (Stereotype)sopraProfile.getOwnedMember(STEREOTYPE_SERVICE_REQUEST);
Stereotype transitionEdgeStereotype = (Stereotype)sopraProfile.getOwnedMember(STEREOTYPE_TRANSITION_EDGE);
// Load the model
URI modelUri = URI.createURI(MODEL_NAME);
ResourceSet modelSet = new ResourceSetImpl();
modelSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
modelSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
modelSet.createResource(modelUri);
Resource modelResource = modelSet.getResource(modelUri, true);
Model model = (Model)EcoreUtil.getObjectByType(modelResource.getContents(), UMLPackage.Literals.MODEL);
EList<Element> elements = model.getOwnedElements();
for(Element e : elements){
if(e instanceof Activity){
Activity activity = (Activity)e;
EList<ActivityEdge> edges = activity.getEdges();
for(ActivityEdge edge : edges){
System.out.println(edge.getValue(transitionEdgeStereotype, "probability"));
}
}
}
An exception is thrown when the getValue method is called upon an element.
The following is the error message:
org.eclipse.uml2.uml.internal.impl.PropertyImpl#7a6d6a3f (name: base_ActivityEdge, visibility: <unset>) (isLeaf: false) (isStatic: false) (isOrdered: false, isUnique: true, isReadOnly: false) (aggregation: none, isDerived: false, isDerivedUnion: false, isID: false)
org.eclipse.uml2.uml.internal.impl.PropertyImpl#255a8ce4 (name: probability, visibility: public) (isLeaf: false) (isStatic: false) (isOrdered: false, isUnique: true, isReadOnly: false) (aggregation: none, isDerived: false, isDerivedUnion: false, isID: false)
Exception in thread "main" java.lang.IllegalArgumentException: org.eclipse.uml2.uml.internal.impl.StereotypeImpl#442f4161 (name: TransitionEdge, visibility: <unset>) (isLeaf: false, isAbstract: false, isFinalSpecialization: false) (isActive: false)
at org.eclipse.uml2.uml.internal.operations.ElementOperations.getValue(ElementOperations.java:527)
at org.eclipse.uml2.uml.internal.impl.ElementImpl.getValue(ElementImpl.java:296)
at test.Test.main(Test.java:68)
I couldn't figure out what was going on. Any suggestions? Thanks a lot!!

The Element.getValue(...) method expects the actual Stereotype instance to be passed, that is used with the model.
In the first block, you are retrieving your Stereotype instance from a separate ResourceSet than the one used for the model in the second block. Consequently, the profile is loaded a second time while loading your model and another Stereotype instance is created. You need to pass that one to Element.getValue(...).
This is the safest way to do it:
Activity activity = ...
Stereotype transitionEdgeStereotype =
activity.getAppliedStereotype(STEREOTYPE_TRANSITION_EDGE);
if (transitionEdgeStereotype != null) {
System.out.println(edge.getValue(transitionEdgeStereotype, "probability"));
}
Edit: In this case, STEREOTYPE_TRANSITION_EDGE needs to be the full qualified name of the stereotype including the profile name, e.g. ServiceProfile::TransitionEdge.

Related

Parameter to disable Sling filter in AEM

I have created a sling filter. Below is a snippet -
#SlingFilter(label = "My filter", description = "Myfilter", metatype = true, generateComponent = true, generateService = true, order = 0, scope = SlingFilterScope.INCLUDE)
public class SlingInoFilter implements Filter {
}
When I deploy my code, I want this filter to be deployed but in a disabled state. Is this achievable?
You can disable it by using ACS commons component disabler:
https://adobe-consulting-services.github.io/acs-aem-commons/features/osgi-disablers/component-disabler/index.html

How do I programmatically set configuration for the ImageResizer SQLReader plugin v4?

I was previously using v3 of ImageResizer but am now trying to use v4.
See: http://imageresizing.net/docs/v4/plugins/sqlreader
I need to programmatically set the several config options for the SQLReader plugin. I had this previous code, but it no longer works, stating that the type SqlReaderSettings could not be found:
// SqlReader Plugin
var fileSettings = new SqlReaderSettings
{
ConnectionString = ApplicationConfigurationContext.Current.DefaultSiteSqlConnectionString,
PathPrefix = "~/Images",
StripFileExtension = true,
ImageIdType = SqlDbType.UniqueIdentifier,
ImageBlobQuery = ???,
ModifiedDateQuery = ???,
ImageExistsQuery = ???,
CacheUnmodifiedFiles = true,
RequireImageExtension = true
};
I cannot use the web.config file to store some of these settings. Specifically the connection string may change at run-time, and cannot be stored un-encrypted in the web.config file due to company policy.
Thanks for the help.
Update: This is the code I now use. I did not add in this plugin from the Web.config as it would be redundant.
new SqlReaderPlugin
{
ConnectionString = ApplicationConfigurationContext.Current.DefaultSiteSqlConnectionString,
ImageIdType = SqlDbType.VarChar,
QueriesAreStoredProcedures = true,
ModifiedDateQuery = "procFileImageResizerSelectTimestamps",
ImageBlobQuery = "procFileImageResizerSelectData",
ExposeAsVpp = true,
VirtualFilesystemPrefix = filesUri,
RequireImageExtension = true,
StripFileExtension = true,
CacheUnmodifiedFiles = true
}.Install(Config.Current);
You can replace SqlReaderSettings with SqlReaderPlugin directly; it no longer uses a separate settings class. Nearly all the class members should be the same, so just change the name of the class you are initializing.

Error "The given key was not present in the dictionary" When Creating New Custom Entity on Update Event

On CRM 2013 on-premise, I'm trying to write a plugin that triggers when an update is made to a field on Quote. The plugin then creates a new custom entity "new_contract".
My plugin is successfully triggered when the update to that field is made. However I keep getting an error message "The given key was not present in the dictionary" when trying to create the new custom entity.
I'm using a "PostImage" in this code. I confirm that it's registered using the same name in Plugin Registration.
Here is the code
var targetEntity = context.GetParameterCollection<Entity>
(context.InputParameters, "Target");
if (targetEntity == null)
{throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Target Entity cannot be null")}
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
{throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Post Image is required");}
var quote = context.GenerateCompositeEntity(targetEntity, postImage);
//throw new InvalidPluginExecutionException(OperationStatus.Failed, "Update is captured");
//Guid QuoteId = (Guid)quote.Attributes["quoteid"];
var serviceFactory = (IOrganizationServiceFactory)serviceProvider
.GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);
var contractEntity = new Entity();
contractEntity = new Entity("new_contract");
if (quote.Attributes.Contains("portfolio"))
{
var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
contractEntity[Schema.new_contract.PortfolioName] =
new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
if (quote.Attributes.Contains(Schema.Quote.QuoteName))
{
var quoteName = (string)quote.Attributes["name"];
contractEntity[Schema.new_contract.contractName] = quoteName;
}
var contractId = service.Create(contractEntity);
I think context does not contain "PostImage" attribute.You should check context to see whether it contains the attribute before getting the data.
Looking at this line in your post above:
var service = serviceFactory.CreateOrganizationService(context.UserId);
I am deducing that the type of your context variable is LocalPluginContext (since this contains the UserId value) which does not expose the images (as another answer states).
To access the images, you need to get to the Plugin Execution Context:
IPluginExecutionContext pluginContext = context.PluginExecutionContext;
Entity postImage = null;
if (pluginContext.PostEntityImages != null && pluginContext.PostEntityImages.Contains("PostImage))
{
postImage = pluginContext.PostEntityImages["PostImage"];
}
In the below code segment, you are checking for the attribute "portfolio" and using "new_portfolio". Can you correct that and let us know whether that worked.
if (quote.Attributes.Contains("portfolio"))
{
var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
contractEntity[Schema.new_contract.PortfolioName] = new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
First, you don't say what line is throwing the exception. Put in the VS debugger and find the line that is throwing the exception.
I did see that you are trying to read from a dictionary here without first checking if the dictionary contains the key, that can be the source of this exception.
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Post Image is required");
Try this:
if(!context.PostEntityImages.Contains("PostImage") ||
context.PostEntityImages["PostImage"] == null)
InvalidPluginExecutionException(OperationStatus.Failed, "Post Image is required");
var postImage = context.PostEntityImages["PostImage"];
Although, I don't think that a PostEntityImage Value will ever be null, if it passes the Contains test you don't really need the null check.

many to many relation gorm table

I have a little problem filtering data...I have a relation many to many.
Sponsor and Old
I have one intermediary table with both ids...
When I log in, my session save a Sponsor id...but when I go to see Old view, appears every Olds... How to access the intermediary table from the OldController or the SponsorController?
In my Oldcontroller I have:
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
def sponsor = Sponsor.findById(session.getAttribute("id"))
def myOld = Old.findAllBySponsor(sponsor, params)
def allMyOld = Old.findAllBySponsor(sponsor)
respond myOld, model:[oldInstanceCount: allMyOld.size()]
//respond Old.list(params), model:[oldInstanceCount: Old.count()]
}
But returns unexpected NullpointerException when processing request: [GET] /oldCare/old/index
No value specified for parameter 2.. Stacktrace follows:
Message: No value specified for parameter 2.
How I access the intermediary table for filtering the olds and appears just the Old associated a one Sponsor?
Assuming you have the following :
class Old {
String title
static hasMany = [sponsours: Sponsour]
}
class Sponsour {
String name
static hasMany = [olds:Old]
}
To find :
def sponsor = Sponsor.load(session.getAttribute("id"))
def allMyOlds = Old.findBySponsour(sponsor,params)

Yet again Entity Framework and FK problems

I have an entity with two fk's. I've been trying to insert a record to the database without success. This are the approaches I've used:
valuePaymentBetToAdd.BetType = db.BetTypes.First(betType => betType.Id == valuePaymentBetToAdd.BetType.Id);
valuePaymentBetToAdd.Lottery = db.Lotteries.First(lotto => lotto.Id == valuePaymentBetToAdd.Lottery.Id);
In this case the second object gets assigned but when calling the SaveChanges method I get an error saying that the properties of the Lottery object were null.
valuePaymentBetToAdd.BetTypeReference.EntityKey = new EntityKey(db.DefaultContainerName + ".BetType", "Id", valuePaymentBetToAdd.BetType.Id);
valuePaymentBetToAdd.LotteryReference.EntityKey = new EntityKey(db.DefaultContainerName + ".Lottery", "Id", valuePaymentBetToAdd.Lottery.Id);
In this case I get another weird error. When the object is being added to the collection.
The object could not be added or attached because its EntityReference has an EntityKey property value that does not match the EntityKey for this object.
Am I missing something in this case?
Try setting the EntityReference like this:
valuePaymentBetToAdd.BetTypeReference.EntityKey = b.BetTypes.First(betType => betType.Id == valuePaymentBetToAdd.BetType.Id).EntityKey;
It works for me
How about creating a stub object for BetType and Lottery where you set only the Id property, and then attach those to their respective EntitySets, and then setting these objects on you Bet object, and save - something like:
Lottery lottery = new Lottery() { Id = valuePaymentBetToAdd.Lottery.Id };
BetType betType = new BetType() { Id = valuePaymentBetToAdd.BetType.Id };
MyContext.AttachTo("Lottery", lottery);
MyContext.AttachTo("BetType", betType);
valuePaymentBetToAdd.Lottery = lottery;
valuePaymentBetToAdd.BetType = betType;
MyContext.AddToBet(valuePaymentBetToAdd);
MyContext.SaveChanges();