package org.eparapher.rcp.views.documents;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;
import org.eparapher.core.tools.JVMSettings;
import org.eparapher.rcp.EPReferences;
import org.eparapher.rcp.actions.CMSDecryptionAction;
import org.eparapher.rcp.actions.CMSEncryptionAction;
import org.eparapher.rcp.actions.CMSSignDocumentAction;
import org.eparapher.rcp.actions.OpenEditorAction;
import org.eparapher.rcp.actions.ToPDFAndSignDocumentAction;
import org.eparapher.rcp.actions.XMLSignDocumentAction;
import org.eparapher.rcp.tools.GUIIcons;
import org.eparapher.rcp.tools.RCPSettings;
/**
* This sample class demonstrates how to plug-in a new
* workbench view. The view shows data obtained from the
* model. The sample creates a dummy model on the fly,
* but a real implementation would connect to the model
* available either in this or another plug-in (e.g. the workspace).
* The view is connected to the model using a content provider.
*
* The view uses a label provider to define how model
* objects should be presented in the view. Each
* view can present the same model objects using
* different labels and icons, if needed. Alternatively,
* a single label provider can be shared between views
* in order to ensure that objects of the same type are
* presented in the same way everywhere.
*
*/
public class SecuredDocumentsView extends ViewPart {
public static final String ID = "org.eparapher.rcp.views.documents.SecuredDocumentsView";
private static Logger log = Logger.getLogger(SecuredDocumentsView.class);
private TreeViewer viewer;
private DrillDownAdapter drillDownAdapter;
private Action cmsSignAction;
private Action cmsSignActionwithwizard;
private Action xmlSignAction;
private Action xmlSignActionwithwizard;
private Action convertAndSignPDFAction;
private Action convertAndSignPDFActionwithwizard;
//private Action verifsignatureAction;
private Action refreshAction;
private Action encryptAction;
private Action encryptwithwizardAction;
private Action decryptAction;
private Action decryptwithwizardAction;
private Action doubleClickAction;
private Action propertyAction;
/*
* The content provider class is responsible for
* providing objects to the view. It can wrap
* existing objects in adapters or simply return
* objects as-is. These objects may be sensitive
* to the current input of the view, or ignore
* it and always show the same content
* (like Task List, for example).
*/
public class TreeObject implements IAdaptable {
protected String name;
private TreeParent parent;
private boolean isReadableDir;
public TreeObject(String name) {
this.name = name;
this.isReadableDir = false;
}
public TreeObject(String name,boolean misReadableDir) {
this.name = name;
this.isReadableDir = false;
}
public String getName() {
return name;
}
public void setParent(TreeParent parent) {
this.parent = parent;
}
public TreeParent getParent() {
return parent;
}
public String getFilePath() {
String fp = getName();
TreeParent tp = getParent();
//Stop when got root parent
while (!tp.getParent().getName().equals("")) {
fp = tp.getName() + java.io.File.separator + fp;
tp = tp.getParent();
}
//Correct a bug on Windows
if (fp.endsWith(java.io.File.separator))
fp = tp.getName() + fp;
else
fp = tp.getName() + java.io.File.separator + fp;
return fp;
}
public String toString() {
return getName();
}
public Object getAdapter(Class key) {
return null;
}
}
public class TreeParent extends TreeObject {
private ArrayList children;
private boolean isRoot;
private int rootnb;
public TreeParent(String name) {
super(name);
children = new ArrayList();
isRoot = false;
}
public void addChild(TreeObject child) {
children.add(child);
child.setParent(this);
}
public void removeChild(TreeObject child) {
children.remove(child);
child.setParent(null);
}
public TreeObject [] getChildren() {
return (TreeObject [])children.toArray(new TreeObject[children.size()]);
}
public boolean hasChildren() {
return children.size()>0;
}
public boolean isRoot() {
return isRoot;
}
public void setRoot(boolean misroot, String mpath) {
isRoot = misroot;
if (isRoot)
this.name = mpath;
}
/*public String getFilePath() {
if (isRoot())
return EPConfig.getSecureDocumentPath();
else
return super.getFilePath();
}*/
}
class ViewLabelProvider extends LabelProvider {
public String getText(Object obj) {
return obj.toString();
}
public Image getImage(Object obj) {
//String imageKey = ISharedImages.IMG_OBJ_FILE;
if (obj instanceof TreeParent) {
TreeParent tp = (TreeParent) obj;
if (tp.isRoot()) {
return GUIIcons.HOME_LOCAL_FILE_ICON;
}
else
return GUIIcons.FILE_ICON_FOLDER; //imageKey = ISharedImages.IMG_OBJ_FOLDER;
}
if (obj instanceof TreeObject) {
TreeObject to = (TreeObject) obj;
return GUIIcons.getIconFromFileExt(to);
}
return GUIIcons.FILE_ICON_DEFAULT;
//return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey);
}
}
class NameSorter extends ViewerSorter {
}
class DocViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {
private TreeParent invisibleRoot;
private TreeParent[] localDocsRoot;
private String[] localDocsPath;
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
public void dispose() {
}
public Object[] getElements(Object parent) {
if (parent.equals(getViewSite())) {
if ( (invisibleRoot==null) || (isRootPathsChanged()) )
initialize();
else refresh();
return getChildren(invisibleRoot);
}
return getChildren(parent);
}
private boolean isRootPathsChanged() {
boolean returnvalue=false;
String[] docpathsconfig = RCPSettings.getSecureDocumentPath();
if (localDocsPath.length!=docpathsconfig.length)
return true;
for (int i = 0; i < localDocsPath.length; i++) {
if (!localDocsPath[i].equals(docpathsconfig[i]))
returnvalue=true;
}
return returnvalue;
}
private void refresh() {
//TODO : do a job if there is a lot of file or if network files
long begin, end;
log.debug("Start refreshing all documents ");
for (int i = 0; i < localDocsPath.length; i++) {
begin = System.currentTimeMillis();
recursiveupdate(localDocsRoot[i], new java.io.File(localDocsPath[i]));
end = System.currentTimeMillis();
log.debug("directory " + localDocsRoot[i] + " refreshed in "+ (end-begin) + " ms");
}
log.debug("Refreshing all documents finished");
}
public Object getParent(Object child) {
if (child instanceof TreeObject) {
return ((TreeObject)child).getParent();
}
return null;
}
public Object [] getChildren(Object parent) {
if (parent instanceof TreeParent) {
return ((TreeParent)parent).getChildren();
}
return new Object[0];
}
public boolean hasChildren(Object parent) {
if (parent instanceof TreeParent)
return ((TreeParent)parent).hasChildren();
return false;
}
/*
* We set up a dummy model to initialize tree heararchy.
* In a real code, you will connect to a real model and
* expose its hierarchy.
*/
private void initialize() {
localDocsPath = RCPSettings.getSecureDocumentPath();
localDocsRoot = new TreeParent[localDocsPath.length];
invisibleRoot = new TreeParent("");
for (int i = 0; i < localDocsPath.length; i++) {
java.io.File rootpath = new java.io.File(localDocsPath[i]);
localDocsRoot[i] = recursiveinit(rootpath);
localDocsRoot[i].setRoot(true,localDocsPath[i]);
invisibleRoot.addChild(localDocsRoot[i]);
}
}
private TreeParent recursiveinit(java.io.File pathToDo) {
java.io.File[] files = pathToDo.listFiles();
TreeParent tp = new TreeParent(pathToDo.getName());
try {
for (int i = 0; i < files.length; i++) {
java.io.File file = files[i];
if (!file.isHidden()&& file.canRead()) {
if (file.isFile()) {
TreeObject to = new TreeObject(file.getName());
tp.addChild(to);
}
if (file.isDirectory()) {
TreeParent subtp = recursiveinit(file);
tp.addChild(subtp);
}
}
}
} catch (Exception e) {
log.debug("Error while creating doc tree for " + pathToDo.getAbsolutePath(),e);
}
return tp;
}
private void recursiveupdate(TreeParent tp, java.io.File pathToCheck) {
java.io.File[] files = pathToCheck.listFiles();
TreeObject[] tos = tp.getChildren();
//Add check : List files in the directory and check if exists in the tree
for (int i = 0; i < files.length; i++) {
java.io.File file = files[i];
int corresponding_index = -1;
//search for corresponding object
for (int j = 0; j < tos.length; j++)
if (file.getName().equals(tos[j].getName()))
corresponding_index = j;
//Not found : new file on FS that is not in the treeview, so add it ...
if (corresponding_index == -1) {
if (!file.isHidden() && file.canRead()) {
if (file.isFile()) {
// New File
TreeObject to = new TreeObject(file.getName());
tp.addChild(to);
}
if (file.isDirectory()) {
//New Directory
TreeParent subtp = recursiveinit(file);
tp.addChild(subtp);
}
}
}
}
//Delete check : List tree and check if the file or directory exists
for (int i = 0; i < tos.length; i++) {
TreeObject to = tos[i];
java.io.File file = new java.io.File(to.getFilePath());
if ( !file.exists() )
tp.removeChild(tos[i]);
else {
if ( file.isDirectory() && (to instanceof TreeParent)) {
TreeParent tp_subdir = (TreeParent) to;
recursiveupdate(tp_subdir,file);
}
//Directory change to file or vice versa
if ( file.isDirectory() && !(to instanceof TreeParent)) {
}
}
}
}
}
/**
* The constructor.
*/
public SecuredDocumentsView() {
}
/**
* This is a callback that will allow us
* to create the viewer and initialize it.
*/
public void createPartControl(Composite parent) {
viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
drillDownAdapter = new DrillDownAdapter(viewer);
viewer.setContentProvider(new DocViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setSorter(new NameSorter());
viewer.setInput(getViewSite());
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
EPReferences.getInstance().setDocviews(this);
//Send the change selection notification to the selection service
getSite().setSelectionProvider(viewer);
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
SecuredDocumentsView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(refreshAction);
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
drillDownAdapter.addNavigationActions(manager);
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(convertAndSignPDFActionwithwizard);
manager.add(cmsSignActionwithwizard);
if (JVMSettings.isJava16Min())
manager.add(xmlSignActionwithwizard);
manager.add(new Separator());
//manager.add(verifsignatureAction);
//drillDownAdapter.addNavigationActions(manager);
}
private void fillContextMenu(IMenuManager manager) {
MenuManager signMenu = new MenuManager("Signature");
signMenu.add(convertAndSignPDFAction);
signMenu.add(convertAndSignPDFActionwithwizard);
signMenu.add(new Separator());
signMenu.add(cmsSignAction);
signMenu.add(cmsSignActionwithwizard);
if (JVMSettings.isJava16Min()) {
signMenu.add(new Separator());
signMenu.add(xmlSignAction);
signMenu.add(xmlSignActionwithwizard);
}
manager.add(signMenu);
MenuManager encryptMenu = new MenuManager("Encryption");
encryptMenu.add(encryptAction);
encryptMenu.add(encryptwithwizardAction);
encryptMenu.add(decryptAction);
manager.add(encryptMenu);
//manager.add(new Separator());
//manager.add(verifsignatureAction);
manager.add(new Separator());
manager.add(refreshAction);
//drillDownAdapter.addNavigationActions(manager);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
manager.add(new Separator());
manager.add(propertyAction);
}
private void makeActions() {
cmsSignAction = new CMSSignDocumentAction(viewer, false);
cmsSignActionwithwizard = new CMSSignDocumentAction(viewer, true);
convertAndSignPDFAction = new ToPDFAndSignDocumentAction(viewer, false);
convertAndSignPDFActionwithwizard = new ToPDFAndSignDocumentAction(viewer, true);
if (JVMSettings.isJava16Min()) {
xmlSignAction = new XMLSignDocumentAction(viewer, false);
xmlSignActionwithwizard = new XMLSignDocumentAction(viewer, true);
//verifsignatureAction = new SignatureVerificationAction();
}
refreshAction = new Action() {
public void run() {viewer.refresh();}
};
refreshAction.setText("Re&fresh");
refreshAction.setToolTipText("Refresh the Tree for added/removed files");
refreshAction.setImageDescriptor(GUIIcons.REFRESH_ICON);
refreshAction.setAccelerator(SWT.F5);
encryptAction = new CMSEncryptionAction(viewer, false);
encryptwithwizardAction = new CMSEncryptionAction(viewer, true);
decryptAction = new CMSDecryptionAction(viewer,false);
encryptAction.setEnabled(true);
encryptwithwizardAction.setEnabled(true);
decryptAction.setEnabled(true);
propertyAction = new PropertyDialogAction(getSite(), viewer);
propertyAction.setImageDescriptor(GUIIcons.INFO_ICON);
doubleClickAction = new OpenEditorAction(viewer);
}
private void hookDoubleClickAction() {
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
doubleClickAction.run();
}
});
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
/*
* IActionBars bars = getViewSite().getActionBars();
* IStatusLineManager statusLine = bars.getStatusLineManager();
* IProgressMonitor pm = statusLine.getProgressMonitor();
*/
public void refreshView() {
long begin = System.currentTimeMillis();
//refresh the view
if (viewer!=null)
viewer.refresh();
long end = System.currentTimeMillis();
log.debug("Time to refresh the document view (in ms) :" + (end-begin));
}
}