org.webcat.core.FilePickerDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.webcat.core.FilePickerDialog.java

Source

/*==========================================================================*\
 |  $Id: FilePickerDialog.java,v 1.5 2012/06/22 16:23:18 aallowat Exp $
 |*-------------------------------------------------------------------------*|
 |  Copyright (C) 2011-2012 Virginia Tech
 |
 |  This file is part of Web-CAT.
 |
 |  Web-CAT is free software; you can redistribute it and/or modify
 |  it under the terms of the GNU Affero General Public License as published
 |  by the Free Software Foundation; either version 3 of the License, or
 |  (at your option) any later version.
 |
 |  Web-CAT is distributed in the hope that it will be useful,
 |  but WITHOUT ANY WARRANTY; without even the implied warranty of
 |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 |  GNU General Public License for more details.
 |
 |  You should have received a copy of the GNU Affero General Public License
 |  along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/

package org.webcat.core;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.webcat.archives.ArchiveManager;
import org.webcat.core.git.GitCommit;
import org.webcat.core.git.GitRef;
import org.webcat.core.git.GitRepository;
import org.webcat.core.git.GitTreeEntry;
import org.webcat.core.git.GitUtilities;
import org.webcat.ui.generators.JavascriptGenerator;
import org.webcat.ui.util.ComponentIDGenerator;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WOResponse;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSData;
import com.webobjects.foundation.NSSet;
import com.webobjects.foundation.NSTimestamp;

//-------------------------------------------------------------------------
/**
 * A modal dialog that lets the user choose a file from any of the
 * repositories that they have access to.
 *
 * @author  Tony Allevato
 * @author  Last changed by $Author: aallowat $
 * @version $Revision: 1.5 $, $Date: 2012/06/22 16:23:18 $
 */
public class FilePickerDialog extends WCComponent {
    //~ Constructors ..........................................................

    // ----------------------------------------------------------
    public FilePickerDialog(WOContext context) {
        super(context);
    }

    //~ KVC attributes (must be public) .......................................

    public String id;
    public String title;

    public RepositoryRefModel refModel;
    public Object repositoryItem;

    public RepositoryEntryModel entryModel;
    public GitTreeEntry entry;

    public RepositoryEntryRef initialSelection;

    public GitRepository createFolderRepo;
    public String createFolderLocation;
    public String newFolderName;
    public String uploadedFilePath;
    public NSData uploadedFileData;
    public String commitMessageForUpload;
    public boolean expandIfArchive;

    public ComponentIDGenerator idFor = new ComponentIDGenerator(this);

    //~ Methods ...............................................................

    // ----------------------------------------------------------
    @Override
    public void appendToResponse(WOResponse response, WOContext context) {
        if (id == null) {
            id = idFor.get();
        }

        updateRefModel();

        super.appendToResponse(response, context);
    }

    // ----------------------------------------------------------
    public String onLoad() {
        updateRefModel();
        return null;
    }

    // ----------------------------------------------------------
    private void updateRefModel() {
        NSArray<? extends EOBase> providers = RepositoryManager.getInstance().repositoriesPresentedToUser(user(),
                localContext());

        refModel = new RepositoryRefModel(providers);

        if (initialSelection != null) {
            refModel.setSelectionFromEntryRef(initialSelection, localContext(), user());
        }

        updateEntryModel();
    }

    // ----------------------------------------------------------
    private GitRef refForModelObject(Object object) {
        GitRef ref;

        if (object instanceof EOBase) {
            GitRepository repo = GitRepository.repositoryForObject((EOBase) object);
            ref = repo.refWithName(Constants.R_HEADS + Constants.MASTER);
        } else {
            ref = (GitRef) object;
        }

        return ref;
    }

    // ----------------------------------------------------------
    private void updateEntryModel() {
        NSSet<?> selectedRefs = refModel.selectedObjects();
        if (selectedRefs.isEmpty()) {
            entryModel = new RepositoryEntryModel(null);
        } else {
            entryModel = new RepositoryEntryModel(refForModelObject(selectedRefs.anyObject())) {
                @Override
                public boolean canSelectObject(GitTreeEntry anEntry) {
                    return delegate.fileCanBeSelected(filePickerItemForEntry(anEntry), anEntry.isTree());
                }
            };

            if (initialSelection != null) {
                entryModel.setSelectionFromEntryRef(initialSelection, localContext());
            }
        }
    }

    // ----------------------------------------------------------
    public boolean canSelectEntry() {
        return entryModel.canSelectObject(entry);
    }

    // ----------------------------------------------------------
    public String cssStyleForItem() {
        if (canSelectEntry()) {
            return null;
        } else {
            return "opacity: 0.4;";
        }
    }

    // ----------------------------------------------------------
    public boolean canModifySelectedBranch() {
        boolean canModify = false;
        Object refModelObject = refModel.selectedObjects().anyObject();
        if (refModelObject != null) {
            GitRef ref = refForModelObject(refModelObject);
            canModify = (ref != null && ref.isMaster());
        }

        return canModify;
    }

    // ----------------------------------------------------------
    public JavascriptGenerator refWasSelected() {
        initialSelection = null;
        updateEntryModel();

        JavascriptGenerator js = new JavascriptGenerator();
        js.refresh(idFor.get("entryTree"));

        if (canModifySelectedBranch()) {
            js.dijit(idFor.get("createFolder")).enable();
            js.dijit(idFor.get("uploadFile")).enable();
        } else {
            js.dijit(idFor.get("createFolder")).disable();
            js.dijit(idFor.get("uploadFile")).disable();
        }

        return js;
    }

    // ----------------------------------------------------------
    public JavascriptGenerator entryWasDoubleClicked() {
        JavascriptGenerator js = new JavascriptGenerator();
        js.dijit(id).call("hide");
        js.append(okPressed());
        return js;
    }

    // ----------------------------------------------------------
    public String displayNameForRepositoryItem() {
        if (repositoryItem instanceof EOBase) {
            return RepositoryManager.getInstance().repositoryNameForObject((EOBase) repositoryItem);
        } else {
            return ((GitRef) repositoryItem).shortName();
        }
    }

    // ----------------------------------------------------------
    public String iconPathForRepositoryItem() {
        if (repositoryItem instanceof EOEnterpriseObject) {
            return "icons/filetypes/drawer.png";
        } else {
            return ((GitRef) repositoryItem).isTag() ? "icons/tag.png" : "icons/node.png";
        }
    }

    // ----------------------------------------------------------
    public Long sizeForEntry() {
        return entry.isTree() ? null : entry.size();
    }

    // ----------------------------------------------------------
    public String iconPathForEntry() {
        return entry.isTree() ? "icons/filetypes/folder.png" : FileUtilities.iconURL(entry.name());
    }

    // ----------------------------------------------------------
    public NSTimestamp lastModifiedTimeForEntry() {
        GitRef ref = refForModelObject(refModel.selectedObjects().anyObject());

        NSArray<GitCommit> commits = entry.repository().commitsWithId(ref.objectId(), entry.path());

        if (commits != null && commits.count() > 0) {
            return commits.objectAtIndex(0).commitTime();
        } else {
            return null;
        }
    }

    // ----------------------------------------------------------
    public FilePickerDelegate delegate() {
        return delegate;
    }

    // ----------------------------------------------------------
    public void setDelegate(FilePickerDelegate delegate) {
        this.delegate = delegate;
    }

    // ----------------------------------------------------------
    private RepositoryEntryRef filePickerItemForEntry(GitTreeEntry anEntry) {
        NSSet<?> selectedRepos = refModel.selectedObjects();

        if (!selectedRepos.isEmpty()) {
            GitRef ref = refForModelObject(selectedRepos.anyObject());

            String providerName = RepositoryManager.getInstance()
                    .repositoryNameForObject(ref.repository().provider());

            String path = anEntry.path();

            if (anEntry.isTree()) {
                path += "/";
            }

            RepositoryEntryRef item = new RepositoryEntryRef(providerName, path, ref.name());

            return item;
        } else {
            return null;
        }
    }

    // ----------------------------------------------------------
    public JavascriptGenerator okPressed() {
        NSSet<GitTreeEntry> selectedEntries = entryModel.selectedObjects();

        if (selectedEntries.isEmpty()) {
            return null;
        } else {
            GitTreeEntry anEntry = selectedEntries.anyObject();

            if (delegate != null) {
                return delegate.fileWasSelected(filePickerItemForEntry(anEntry));
            } else {
                return null;
            }
        }
    }

    // ----------------------------------------------------------
    public JavascriptGenerator displayCreateFolderDialog() {
        return showModifierDialog("createFolderDialog");
    }

    // ----------------------------------------------------------
    public JavascriptGenerator createFolderOkPressed() {
        JavascriptGenerator js = new JavascriptGenerator();
        js.dijit(idFor.get("createFolderDialog")).call("hide");

        Repository workingCopy = GitUtilities.workingCopyForRepository(createFolderRepo.repository(), true);
        File file = workingCopy.getWorkTree();
        File destDir = file;

        if (createFolderLocation != null) {
            destDir = new File(file, createFolderLocation);
        }

        File newFolder = new File(destDir, newFolderName);
        if (newFolder.exists()) {
            js.alert("Notice", "The folder already exists.");
            return js;
        }

        try {
            newFolder.mkdirs();
            File gitIgnore = new File(newFolder, ".gitignore");
            FileOutputStream os = new FileOutputStream(gitIgnore);
            os.close();
            GitUtilities.pushWorkingCopyImmediately(workingCopy, user(),
                    "Created folder \"" + newFolderName + "\"");
        } catch (Exception e) {
            log.error("error creating the folder " + newFolderName + " as " + newFolder + ": ", e);

            js.alert("Notice", "The following error occurred trying to create " + "the folder \"" + newFolderName
                    + "\": " + e.getMessage());
            return js;
        }

        updateRefModel();

        js.refresh(idFor.get("repositoryTree"), idFor.get("entryTree"));
        return js;
    }

    // ----------------------------------------------------------
    private JavascriptGenerator showModifierDialog(String dialogId) {
        NSSet<?> selectedRepos = refModel.selectedObjects();

        if (selectedRepos.isEmpty()) {
            return new JavascriptGenerator().alert("Notice",
                    "You must select the master branch of a " + "repository first.");
        }

        if (!canModifySelectedBranch()) {
            return new JavascriptGenerator().alert("Notice",
                    "You may only modify the master branch of a " + "repository through the web interface.");
        }

        GitRef ref = refForModelObject(selectedRepos.anyObject());

        createFolderRepo = ref.repository();

        NSSet<GitTreeEntry> selectedEntries = entryModel.selectedObjects();

        if (selectedEntries.isEmpty()) {
            createFolderLocation = null;
        } else {
            GitTreeEntry anEntry = selectedEntries.anyObject();

            if (anEntry.isTree()) {
                createFolderLocation = anEntry.path();
            } else {
                File file = new File(anEntry.path());
                createFolderLocation = file.getParent();
            }
        }

        JavascriptGenerator js = new JavascriptGenerator();
        js.dijit(idFor.get(dialogId)).call("show");
        return js;
    }

    // ----------------------------------------------------------
    public JavascriptGenerator displayUploadFileDialog() {
        if (commitMessageForUpload == null) {
            commitMessageForUpload = "Uploaded from my web browser";
        }

        return showModifierDialog("uploadFileDialog");
    }

    // ----------------------------------------------------------
    public JavascriptGenerator fileWasUploaded() {
        uploadedFilePath = new File(uploadedFilePath).getName();

        JavascriptGenerator js = new JavascriptGenerator();

        // FIXME Why doesn't this code run on the production server? Problem
        // because it gets sent back in a textarea due to iframe I/O weirdness?

        /*        boolean isArchive = FileUtilities.isArchiveFile(uploadedFilePath);
            
                js.style(idFor.get("expandIfArchiveContainer"), "visibility",
            isArchive ? "visible" : "hidden");
            
                js.dijit(idFor.get("uploadFileOk")).enable();*/
        return js;
    }

    // ----------------------------------------------------------
    public JavascriptGenerator uploadFileOkPressed() {
        JavascriptGenerator js = new JavascriptGenerator();
        js.dijit(idFor.get("uploadFileDialog")).call("hide");

        if (uploadedFilePath == null) {
            return js;
        }

        Repository workingCopy = GitUtilities.workingCopyForRepository(createFolderRepo.repository(), true);
        File file = workingCopy.getWorkTree();
        File destDir = file;

        if (createFolderLocation != null) {
            destDir = new File(file, createFolderLocation);
        }

        File destFile = new File(destDir, uploadedFilePath);

        try {
            if (expandIfArchive && FileUtilities.isArchiveFile(uploadedFilePath)) {
                ArchiveManager.getInstance().unpack(destDir, uploadedFilePath, uploadedFileData.stream());
            } else {
                FileOutputStream os = new FileOutputStream(destFile);
                uploadedFileData.writeToStream(os);
                os.close();
            }

            GitUtilities.pushWorkingCopyImmediately(workingCopy, user(), commitMessageForUpload);
        } catch (IOException e) {
            log.error("error uploading file " + uploadedFilePath + " as " + destFile + ": ", e);
            js.alert("Error", "The following error occurred trying to upload the " + "file \"" + uploadedFilePath
                    + "\": " + e.getMessage());
            return js;
        }

        updateRefModel();

        js.refresh(idFor.get("repositoryTree"), idFor.get("entryTree"));
        return js;
    }

    //~ Static/instance variables .............................................

    private FilePickerDelegate delegate;
}