/* (non-Javadoc)
  * @see org.eclipse.graphiti.features.IFeature#canExecute(org.eclipse.graphiti.features.context.IContext)
  */
 @Override
 public boolean canExecute(IContext context) {
   // TODO: clean this mess up: use {@code getWorkItemEditor()) to check if the selected task
   // has a WID and if the WID defines a customEditor
   BPMN2Editor editor =
       (BPMN2Editor)
           getFeatureProvider()
               .getDiagramTypeProvider()
               .getDiagramBehavior()
               .getDiagramContainer();
   IBpmn2RuntimeExtension rte = editor.getTargetRuntime().getRuntimeExtension();
   if (rte instanceof JBPM5RuntimeExtension && context instanceof ICustomContext) {
     PictogramElement[] pes = ((ICustomContext) context).getPictogramElements();
     if (pes.length == 1) {
       Object o = Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(pes[0]);
       if (o instanceof Task) {
         Task task = (Task) o;
         List<EStructuralFeature> features = ModelDecorator.getAnyAttributes(task);
         for (EStructuralFeature f : features) {
           if ("taskName".equals(f.getName())) { // $NON-NLS-1$
             // make sure the Work Item Definition exists
             String taskName = (String) task.eGet(f);
             return ((JBPM5RuntimeExtension) rte).getWorkItemDefinition(taskName) != null;
           }
         }
       }
     }
   }
   return false;
 }
  public String getId(EObject object) {
    if (object == null) return null;

    List<EStructuralFeature> features = ModelDecorator.getAnyAttributes(object);
    for (EStructuralFeature f : features) {
      if ("taskName".equals(f.getName())) { // $NON-NLS-1$
        Object attrValue = object.eGet(f);
        if (attrValue != null) {
          // search the extension attributes for a "taskName" and compare it
          // against the new object's taskName value
          for (Property p : customTaskDescriptor.getProperties()) {
            String propValue = p.getFirstStringValue();
            if (attrValue.equals(propValue)) return getId();
          }
        }
      }
    }
    return null;
  }
  void suggestNextActivityId(Event currentEvent, Task task) {
    // now test if the id is valid or suggest a new one...
    EStructuralFeature feature = ModelDecorator.getAnyAttribute(currentEvent, "activityid");
    if (feature != null) {

      List<Event> dataProtectionEvents = new ArrayList<Event>();
      new Tracer().findDataProtectionTargetEvents(task, dataProtectionEvents);
      new Tracer().findDataProtectionStartEvents(task, dataProtectionEvents);

      logger.fine("found " + dataProtectionEvents.size() + " Imxis Events");

      Integer currentActivityID = (Integer) currentEvent.eGet(feature);
      int bestID = -1;
      boolean duplicateID = false;
      for (Event aEvent : dataProtectionEvents) {

        if (aEvent == currentEvent) continue;

        int aID = (Integer) aEvent.eGet(feature);
        if (aID > bestID) bestID = aID;

        // test for dupplicates!
        if (aID == currentActivityID) {
          duplicateID = true;
        }
      }

      // if duplicate or currentID<=0 suggest a new one!
      if (duplicateID || currentActivityID <= 0) {
        if (bestID <= 0) currentActivityID = DEFAULT_ACTIVITY_ID;
        else currentActivityID = bestID + 10;
      }
      // suggest a new ProcessID...
      logger.fine("ActiviytID=" + currentActivityID);
      currentEvent.eSet(feature, currentActivityID);
    }
  }
    /* (non-Javadoc)
     * @see org.eclipse.graphiti.features.IFeature#execute(org.eclipse.graphiti.features.context.IContext)
     */
    @Override
    public void execute(IContext context) {
      // TODO: clean this mess up: use {@code getWorkItemEditor()) to check if the selected task
      // has a WID and if the WID defines a customEditor
      BPMN2Editor editor =
          (BPMN2Editor)
              getFeatureProvider()
                  .getDiagramTypeProvider()
                  .getDiagramBehavior()
                  .getDiagramContainer();
      PictogramElement pe = ((ICustomContext) context).getPictogramElements()[0];
      final Task task =
          (Task) Graphiti.getLinkService().getBusinessObjectForLinkedPictogramElement(pe);
      String taskName = ""; // $NON-NLS-1$
      List<EStructuralFeature> features = ModelDecorator.getAnyAttributes(task);
      for (EStructuralFeature f : features) {
        if ("taskName".equals(f.getName())) { // $NON-NLS-1$
          taskName = (String) task.eGet(f);
          break;
        }
      }

      IBpmn2RuntimeExtension rte = editor.getTargetRuntime().getRuntimeExtension();
      WorkItemDefinition workItemDefinition =
          ((JBPM5RuntimeExtension) rte).getWorkItemDefinition(taskName);

      WorkDefinitionImpl wd = new WorkDefinitionImpl();
      for (String name : workItemDefinition.getParameters().keySet()) {
        String type = workItemDefinition.getParameters().get(name);
        DataTypeFactory factory = DataTypeRegistry.getFactory(type);
        wd.addParameter(new ParameterDefinitionImpl(name, factory.createDataType()));
      }

      WorkImpl w = new WorkImpl();
      w.setName(taskName);
      w.setParameterDefinitions(wd.getParameters());
      for (DataInputAssociation dia : task.getDataInputAssociations()) {
        DataInput dataInput = (DataInput) dia.getTargetRef();
        if (dataInput != null) {
          String name = dataInput.getName();
          ItemDefinition itemDefinition = dataInput.getItemSubjectRef();
          if (itemDefinition != null) {
            Object structureRef = itemDefinition.getStructureRef();
            if (ModelUtil.isStringWrapper(structureRef)) {
              ParameterDefinition parameterDefinition = w.getParameterDefinition(name);
              try {
                Object value =
                    parameterDefinition
                        .getType()
                        .readValue(ModelUtil.getStringWrapperTextValue(structureRef));
                w.setParameter(name, value);
              } catch (Exception e) {
              }
            }
          }
        }
      }

      /*
      	 * Load the class defined in the WID's "eclipse:customEditor" field.
      	 * This means that the containing Project must be a JavaProject, and
      	 * the class must exist and must implement the WorkEditor interface.
      try {
      	Resource res = ExtendedPropertiesAdapter.getResource(task);
      	URI uri = res.getURI();
      	IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(uri.segment(1));
      	JavaProjectClassLoader cl = new JavaProjectClassLoader(project);
      	Class c = cl.loadClass("org.bpmn2.java.Calculator");
      	Object o = c.newInstance();
      	String s = o.toString();
      	System.out.println(s);
      } catch (Exception e) {
      	// TODO Auto-generated catch block
      	e.printStackTrace();
      }
      	 */

      WorkEditor dialog = getWorkItemEditor(task);
      dialog.setWorkDefinition(wd);
      dialog.setWork(w);
      dialog.show();

      hasChanges = dialog.getWork() != w;
      if (hasChanges) {
        w = (WorkImpl) dialog.getWork();
        for (DataInputAssociation dia : task.getDataInputAssociations()) {
          DataInput dataInput = (DataInput) dia.getTargetRef();
          if (dataInput != null) {
            String name = dataInput.getName();
            ItemDefinition itemDefinition = dataInput.getItemSubjectRef();
            // this always comes back as a String from the SampleCustomEditor dialog
            String value = (String) w.getParameter(name);
            if (value != null && !value.isEmpty()) {
              EObject structureRef = ModelUtil.createStringWrapper(value);
              if (itemDefinition == null) {
                itemDefinition =
                    Bpmn2ModelerFactory.createObject(task.eResource(), ItemDefinition.class);
                ModelUtil.getDefinitions(task).getRootElements().add(itemDefinition);
                ModelUtil.setID(itemDefinition);
              }
              itemDefinition.setItemKind(ItemKind.INFORMATION);
              itemDefinition.setStructureRef(structureRef);
              dataInput.setItemSubjectRef(itemDefinition);
            } else if (itemDefinition != null) {
              // TODO: remove Item Definition if it is on longer referenced anywhere
              //							ModelUtil.getDefinitions(task).getRootElements().remove(itemDefinition);
              dataInput.setItemSubjectRef(null);
            }
          }
        }
      }
    }