예제 #1
0
  /**
   * Synchronize the selected project subtree to the file system. This methods requires the correct
   * starting level on the file system with respect to the project subtree to exist.
   *
   * <p>Important to note that this method synchronize only the SUBTREE 'under' the last tree node
   * in the treePath variable.
   *
   * @param fsLevel is the starting point for the synchronization on the file system
   * @param treePath is the starting point in the project structure for the synchronization
   * @param addProjectItems indicates whether new items are supposed to be created on the file
   *     system if they are missing
   * @param overwriteProjectItems indicates whether diagrams that already exists on the file system
   *     are supposed to be overwritten
   * @param deleteProjectItems indicates whether not projects items (files or diagrams) are supposed
   *     to be deleted from file system
   * @return true if and only if no error occurs, false otherwise
   * @throws InterruptedException when user cancels the synchronization
   */
  private boolean syncSubtreeToFS(
      final File fsLevel,
      final TreePath treePath,
      final boolean addProjectItems,
      final boolean overwriteProjectItems,
      final boolean deleteProjectItems)
      throws InterruptedException {

    checkInterruption();

    boolean retValue = true;

    final DefaultMutableTreeNode lastTreePathNode =
        (DefaultMutableTreeNode) treePath.getLastPathComponent();
    final Object userObject = lastTreePathNode.getUserObject();
    final ProjectItem projectItem;

    projectItem = (ProjectItem) userObject;

    // sync a project diagram
    if (userObject instanceof ProjectDiagram) {
      final ProjectDiagram projectDiagram = (ProjectDiagram) userObject;
      final String fileExtension =
          ProjectServiceUtils.getNotationFileExtension(projectDiagram.getNotationIdentifier());

      final File projectItemFile =
          new File(fsLevel.getAbsolutePath(), projectItem.getDisplayName() + fileExtension);

      NotationLocalIOController.SaveResult successSaveResult =
          NotationLocalIOController.SaveResult.SUCCESS;

      if (projectItemFile.exists() && overwriteProjectItems) {
        successSaveResult =
            ModelerSession.getNotationService()
                .getNotation(projectDiagram.getNotationIdentifier())
                .getLocalIOController()
                .saveProjectDiagram(projectDiagram, projectItemFile.getParent(), false);

        if (successSaveResult == NotationLocalIOController.SaveResult.SUCCESS) {
          LOG.debug(
              "Sync PN -> FS: Diagram "
                  + projectItemFile.getAbsolutePath()
                  + " has been overwritten.");

        } else {
          publicOverwriteError(projectDiagram, projectItemFile);
        }

      } else if (!projectItemFile.exists() && addProjectItems) {
        successSaveResult =
            ModelerSession.getNotationService()
                .getNotation(projectDiagram.getNotationIdentifier())
                .getLocalIOController()
                .saveProjectDiagram(projectDiagram, projectItemFile.getParent(), false);

        if (successSaveResult == NotationLocalIOController.SaveResult.SUCCESS) {
          LOG.debug(
              "Sync PN -> FS: Diagram " + projectItemFile.getAbsolutePath() + " has been saved.");
        } else {
          publicAddDiagramError(projectDiagram, projectItemFile);
        }
      }

      if (successSaveResult != NotationLocalIOController.SaveResult.SUCCESS) {
        retValue = false;
      }

      // user object is project root or a subfolder
    } else if (userObject instanceof ProjectContainer) {
      final Set<String> synchronizedItems = new HashSet<String>();

      if (userObject instanceof ProjectRoot) {
        // add project file (.pmp) to the list of synchronizedItems = do not delete it
        synchronizedItems.add(
            (((ProjectItem) userObject)).getDisplayName() + ProjectService.PROJECT_FILE_EXTENSION);
      }

      for (int i = 0; i < lastTreePathNode.getChildCount(); i++) {
        checkInterruption();

        final DefaultMutableTreeNode defaultMutableTreeNode =
            (DefaultMutableTreeNode) lastTreePathNode.getChildAt(i);
        final ProjectItem projectItemOfChildNode =
            (ProjectItem) defaultMutableTreeNode.getUserObject();

        final File projectItemFile;
        if (projectItemOfChildNode instanceof ProjectContainer) {
          // project containers are without file extension
          projectItemFile =
              new File(fsLevel.getAbsolutePath(), projectItemOfChildNode.getDisplayName());
        } else if (projectItemOfChildNode instanceof ProjectDiagram) {
          // project diagram files do have a file extension
          final String fileExtension =
              ProjectServiceUtils.getNotationFileExtension(
                  ((ProjectDiagram) projectItemOfChildNode).getNotationIdentifier());
          projectItemFile =
              new File(
                  fsLevel.getAbsolutePath(),
                  projectItemOfChildNode.getDisplayName() + fileExtension);
        } else {
          LOG.error("A project item has to be either project container or project diagram.");
          syncDialog.appendErrorInfo(INVALID_PARENT_ERROR_LABEL, true);
          return false;
        }

        if (projectItemFile.exists()) {
          if (projectItemOfChildNode instanceof ProjectDiagram) {
            retValue &=
                syncSubtreeToFS(
                    projectItemFile.getParentFile(),
                    treePath.pathByAddingChild(defaultMutableTreeNode),
                    addProjectItems,
                    overwriteProjectItems,
                    deleteProjectItems);

          } else {
              /* next child is container */
            retValue &=
                syncSubtreeToFS(
                    projectItemFile,
                    treePath.pathByAddingChild(defaultMutableTreeNode),
                    addProjectItems,
                    overwriteProjectItems,
                    deleteProjectItems);
          }

          synchronizedItems.add(projectItemFile.getName());

        } else if (!projectItemFile.exists() && addProjectItems) {

          /* next child is diagram */
          if (projectItemOfChildNode instanceof ProjectDiagram) {

            final String fileExtension =
                ProjectServiceUtils.getNotationFileExtension(
                    ((ProjectDiagram) projectItemOfChildNode).getNotationIdentifier());

            retValue &=
                syncSubtreeToFS(
                    projectItemFile.getParentFile(),
                    treePath.pathByAddingChild(defaultMutableTreeNode),
                    addProjectItems,
                    overwriteProjectItems,
                    deleteProjectItems);

            synchronizedItems.add(projectItemOfChildNode.getDisplayName() + fileExtension);

          } else {
              /* next child is container */

            if (projectItemFile.mkdir()) { // make new subfolder
              LOG.debug(
                  "Sync PN -> FS: new subfolder has been created, "
                      + projectItemFile.getAbsolutePath()
                      + ".");

              retValue &=
                  syncSubtreeToFS(
                      projectItemFile,
                      treePath.pathByAddingChild(defaultMutableTreeNode),
                      addProjectItems,
                      overwriteProjectItems,
                      deleteProjectItems);

              synchronizedItems.add(projectItemOfChildNode.getDisplayName());

            } else {
              publicMkdirError(projectItemFile);
            }
          }
        }
      }

      // delete non PN items in this fs level
      if (deleteProjectItems) {
        final String[] fsLevelItems = fsLevel.list();

        for (final String fsItem : fsLevelItems) {
          if (!synchronizedItems.contains(fsItem)) { // delete not PN item from FS
            final File itemToDelete = new File(fsLevel.getAbsolutePath(), fsItem);

            if (ProjectServiceUtils.removeDirectory(itemToDelete)) {
              LOG.debug("File system item has been deleted, " + itemToDelete.getAbsolutePath());

            } else {
              publicDeleteError(itemToDelete);
              retValue = false;
            }
          }
        }
      }
    }

    return retValue;
  }
예제 #2
0
  /**
   * Prepares the synchronization process and starts the synchronization.
   *
   * @return true if there were no errors during synchronization process, false otherwise
   * @throws Exception when something happened, synchronize(...) (see above) method deals with
   *     possible problems
   */
  protected Boolean doInBackground() throws Exception {
    showDialog();

    // First goes the JTree main projects root (root node, invisible for users) and then a project
    // root node.
    if (!ProjectServiceUtils.isValidTreePath(treePath) || treePath.getPathCount() < 2) {
      LOG.error("Invalid tree path.");
      syncDialog.appendErrorInfo(INVALID_TREE_PATH_LABEL, true);
      return false;
    }

    final DefaultMutableTreeNode projectRootNode;
    final ProjectRoot projectRoot;
    try {
      projectRootNode = (DefaultMutableTreeNode) treePath.getPathComponent(1);
      projectRoot = (ProjectRoot) projectRootNode.getUserObject();
    } catch (ClassCastException exception) {
      // should never happened, because isValidTreePath() method ensures this; testing & debuging
      // purposes
      LOG.error("Project root not found.");
      syncDialog.appendErrorInfo(PROJECT_ROOT_NOT_FOUND_LABEL, true);
      return false;
    }

    final File projectRootFile =
        new File(
            projectRoot.getProjectLocation(),
            projectRoot.getDisplayName() + ProjectService.PROJECT_FILE_EXTENSION);

    if (projectRootFile.exists()
        && overwriteProjectItems
        &&
        /* overwrite project file only when the project root is set as tree path (constructor argument) */
        treePath.equals(
            ModelerSession.getProjectService().getProjectPath(projectRoot.getDisplayName()))) {

      final SaveProjectResult result =
          ModelerSession.getProjectControlService()
              .saveProject(treePath); // overwrite the project file
      if (!SaveProjectResult.SUCCESS.equals(result)) {
        LOG.error("Not possible to save project file");
        syncDialog.appendErrorInfo(IMPOSSIBLE_TO_SAVE_PROJECT_FILE_LABEL, true);
        return false;
      }

    } else if (!projectRootFile.exists() && addProjectItems) {
      final SaveProjectResult result =
          ModelerSession.getProjectControlService()
              .saveProject(treePath); // create the project file
      if (!SaveProjectResult.SUCCESS.equals(result)) {
        LOG.error("Not possible to save project file");
        syncDialog.appendErrorInfo(IMPOSSIBLE_TO_SAVE_PROJECT_FILE_LABEL, true);
        return false;
      }

    } else if (!projectRootFile.exists()) {
      LOG.error(
          "Project file not found and synchronization is not allowed to add items to the file system.");
      syncDialog.appendErrorInfo(MISSING_PROJECT_FILE_LABEL, true);
      return false;
    }

    final File path =
        syncPathToTreeRootToFS(new File(projectRootFile.getParent()), treePath, addProjectItems);

    if (path == null) {
      syncDialog.appendErrorInfo(SYNC_SUBTREE_BUILD_ERROR_LABEL, true);
      return false;
    }

    /* This is kind of hack to show, that there is no need to continue,
    there are still differences between FS and PN, but the method is not allowed to create FS items. */
    return path.getAbsolutePath().equals("")
        || syncSubtreeToFS(
            path, treePath, addProjectItems, overwriteProjectItems, deleteProjectItems);
  }