/**
  * Handle the case when a stereotype application is removed : - Forbid direct removal of a
  * duplicated profile application (with eAnnotation) - Inspect controlled sub-packages - Remove
  * duplicated profile applications on these (with eAnnotation)
  *
  * @param packageElement the package from which stereotype application has been removed
  * @param profileAppl the removed profile application
  * @param profile the unapplied profile
  * @return whether removal is allowed
  */
 private boolean stereotypeApplicationRemoved(
     Package packageElement, ProfileApplication profileAppl, Profile profile) {
   // Forbid direct removal of a duplicated profile application (with eAnnotation)
   if (ProfileApplicationHelper.isDuplicatedProfileApplication(profileAppl)) {
     Package parentPack =
         ProfileApplicationHelper.getParentPackageWithProfile(packageElement, profile, true);
     // restore stereotype application when it is called from parent intermediate package
     ProfileApplicationHelper.duplicateProfileApplication(packageElement, profile);
     String msg;
     if (parentPack != null) {
       msg =
           NLS.bind(
               Messages.warning_cannot_delete_duplicated,
               EMFCoreUtil.getQualifiedName(packageElement, true),
               EMFCoreUtil.getQualifiedName(parentPack, true));
     } else {
       // parent package can not be reached as it is in a different maybe not accessible resource
       // (working on controlled resource)
       msg =
           NLS.bind(
               Messages.warning_cannot_delete_duplicated_alt,
               EMFCoreUtil.getQualifiedName(packageElement, true));
     }
     NotificationBuilder notifBuild = NotificationBuilder.createAsyncPopup(msg);
     notifBuild.run();
     return true;
   }
   // Inspect controlled sub-packages
   Set<Package> controlledPack = getControlledSubPackages(packageElement);
   boolean update = checkControlledPackagesUpdateable(controlledPack);
   if (update) {
     for (Package pack : controlledPack) {
       ProfileApplicationHelper.removeProfileApplicationDuplication(pack, profile, false);
     }
     return true;
   } else {
     return false;
   }
 }
 public boolean loadResource(ModelSet modelSet, URI uri) {
   // pathmap resource are always loaded
   boolean result = !uri.isPlatform() && !uri.isFile();
   if (!result) {
     URI lastInitialURI = SashModelUtils.getInitialURI(modelSet).trimFileExtension();
     if (!lastInitialURI.equals(initialURI)) {
       clear();
       initialURI = lastInitialURI;
     }
     URI uritrimFragment = uri.trimFragment().trimFileExtension();
     Set<String> extensions = mappingURIExtensions.get(uritrimFragment);
     if (extensions == null) {
       extensions = new HashSet<String>();
       mappingURIExtensions.put(uritrimFragment, extensions);
     }
     extensions.add(uri.fileExtension());
     result = lastInitialURI.equals(uritrimFragment);
     if (!result) {
       result = alreadyValidated.contains(uritrimFragment);
       if (!result) {
         if (!alreadyGuessed.contains(uritrimFragment)) {
           String message =
               new StringBuffer("<form><p>Your model is linked to an external resource (")
                   .append(uritrimFragment.toString())
                   .append(").</p><p>Do you want to load it ?</p></form>")
                   .toString();
           NotificationBuilder builder = getNotification(message, uritrimFragment, modelSet);
           builder.run();
           alreadyGuessed.add(uritrimFragment);
           // notification
         }
       }
     }
   }
   return result;
 }
  protected NotificationBuilder getNotification(
      String message, final URI uri, final ModelSet modelSet) {
    Runnable yes =
        new Runnable() {

          private DiSashModelMngr sashModelMngr;

          private IPageMngr pageMngr;

          public void run() {
            Set<URI> alreadyLoaded = new HashSet<URI>();
            IEditorPart editor = getEditor();
            if (editor instanceof CoreMultiDiagramEditor) {
              CoreMultiDiagramEditor core = (CoreMultiDiagramEditor) editor;
              try {
                sashModelMngr = core.getServicesRegistry().getService(DiSashModelMngr.class);
                pageMngr = sashModelMngr.getIPageMngr();
                List<Object> allPages = pageMngr.allPages();
                // the uri is added after getting all the pages. If it is done before, the eobjects
                // are resolved
                alreadyValidated.add(uri);
                NotificationBuilder error =
                    NotificationBuilder.createAsyncPopup(
                            "Error", String.format("Unable to load resource %s", uri.toString()))
                        .setType(Type.ERROR)
                        .setDelay(2000);
                for (Object o : allPages) {
                  if (o instanceof EObject) {
                    EObject eobject = (EObject) o;
                    if (eobject.eIsProxy()) {
                      InternalEObject internal = (InternalEObject) eobject;
                      URI uriProxy = internal.eProxyURI();
                      URI trimFragment = uriProxy.trimFragment();
                      if (uri.equals(trimFragment.trimFileExtension())) {
                        try {
                          Resource r = modelSet.getResource(trimFragment, true);
                          alreadyLoaded.add(trimFragment);
                          if (r != null) {
                            EObject eObject = r.getEObject(uriProxy.fragment());
                            pageMngr.closePage(eObject);
                            pageMngr.openPage(eObject);
                          } else {
                            error.run();
                          }
                        } catch (Exception e) {
                          error.run();
                          e.printStackTrace();
                        }
                      }
                    }
                  }
                }
                Set<String> extensions = mappingURIExtensions.get(uri);
                if (extensions != null) {
                  for (String s : extensions) {
                    try {
                      URI uriToLoad = URI.createURI(uri.toString());
                      if (s != null) {
                        uriToLoad = uriToLoad.appendFileExtension(s);
                      }
                      if (!alreadyLoaded.contains(uriToLoad)) {
                        Resource r = modelSet.getResource(uriToLoad, true);
                        if (r == null) {
                          error.run();
                        }
                      }
                    } catch (Exception re) {
                      error.run();
                      re.printStackTrace();
                    }
                  }
                }
              } catch (ServiceException e) {
              }
            }
          }
        };
    Runnable no =
        new Runnable() {

          public void run() {}
        };
    return NotificationBuilder.createYesNo(message, yes, no)
        .setHTML(true)
        .setAsynchronous(true)
        .setTitle("Load resource " + uri.toString());
  }
  /**
   * Check if controlled sub-packages can be correctly updated : - Check if controlled package is
   * loaded - Change the control strategy if necessary - Report error if the controlled package is
   * read-only
   *
   * @param controlledPackages the controlled sub-packages (may be updated if contains proxies)
   * @return true if can be updated
   */
  private boolean checkControlledPackagesUpdateable(Set<Package> controlledPackages) {
    boolean notLoadedPackages = false;
    StringBuffer notLoadedPackagesList = new StringBuffer();
    boolean readOnlyPackages = false;
    StringBuffer readOnlyPackagesList = new StringBuffer();
    // Check if controlled package is loaded
    for (Iterator<Package> iterator = controlledPackages.iterator(); iterator.hasNext(); ) {
      Package pack = iterator.next();
      EditingDomain domain = EditorUtils.getTransactionalEditingDomain();
      if (pack.eIsProxy()) {
        EObject loadedObject =
            domain.getResourceSet().getEObject(((InternalEObject) pack).eProxyURI(), true);
        if (loadedObject != null) {
          // pack has been reload, replace proxy;
          controlledPackages.remove(pack);
          pack = (Package) loadedObject;
          controlledPackages.add(pack);
        }
      }
      if (pack.eIsProxy()) {
        notLoadedPackages = true;
        URI uri = ((InternalEObject) pack).eProxyURI();
        String uriLastSeg = uri.lastSegment();
        String name =
            uriLastSeg.substring(0, uriLastSeg.length() - uri.fileExtension().length() - 1);
        String qualifName =
            EMFCoreUtil.getQualifiedName(pack.getOwner(), true)
                .concat("::")
                .concat(name); // $NON-NLS-1$
        notLoadedPackagesList.append(String.format(ENTRY_FORMAT, qualifName));
      } else {
        if (domain instanceof AdapterFactoryEditingDomain) {
          // reset read-only cache map
          ((AdapterFactoryEditingDomain) domain).getResourceToReadOnlyMap().clear();
        }
        if (domain.isReadOnly(pack.eResource())) {
          readOnlyPackages = true;
          String name = EMFCoreUtil.getQualifiedName(pack, true);
          readOnlyPackagesList.append(String.format(ENTRY_FORMAT, name));
        }
      }
    }
    // Report error if the controlled package is read-only
    if (readOnlyPackages) {
      String msg = NLS.bind(Messages.error_readonly, readOnlyPackagesList.toString());
      NotificationBuilder notifBuild = NotificationBuilder.createErrorPopup(msg);
      notifBuild.setHTML(true);
      notifBuild.run();
      return false;
    }
    // Change the control strategy if necessary
    if (notLoadedPackages) {
      String msg = NLS.bind(Messages.switch_loading_strategy, notLoadedPackagesList.toString());
      final BooleanResult stategyChanged = new BooleanResult();
      Runnable runStrategySwitch =
          new Runnable() {

            public void run() {
              StrategyChooser.setCurrentStrategy(LOAD_ALL_STRATEGY);
              stategyChanged.setValue(true);
            }
          };
      Runnable cancel =
          new Runnable() {

            public void run() {
              stategyChanged.setValue(false);
            }
          };
      NotificationBuilder notifBuild =
          NotificationBuilder.createYesNo(msg, runStrategySwitch, cancel);
      notifBuild.setHTML(true);
      notifBuild.setAsynchronous(false);
      notifBuild.run();
      if (stategyChanged.getValue()) {
        // refresh set controlledPackages
        return checkControlledPackagesUpdateable(controlledPackages);
      } else {
        return false;
      }
    }
    return true;
  }