/* * Copyright 2005 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.eclipse.action; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.jbpm.process.workitem.WorkDefinitionImpl; import org.jbpm.process.workitem.WorkItemRepository; /** * Dialog for importing workitems. */ public class ImportWorkItemsDialog extends Dialog { private static final String EOL = System.getProperty( "line.separator" ); private TreeViewer treeViewer; private Text urlText; private Button importButton; private Browser documentation; private IJavaProject project; private Button addToConfigFile; private Button addLibraries; private Button registerHandlers; public ImportWorkItemsDialog(IJavaProject project, Shell parentShell) { super(parentShell); this.project = project; setShellStyle(getShellStyle() | SWT.RESIZE); } protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Import services"); } protected Point getInitialSize() { return new Point(600, 800); } protected Control createDialogArea(Composite parent) { Composite top = (Composite) super.createDialogArea(parent); top.setLayout(new FillLayout()); SashForm sashForm = new SashForm(top, SWT.VERTICAL); Composite composite = new Composite(sashForm, SWT.NONE); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 4; composite.setLayout(gridLayout); Label label = new Label(composite, SWT.NONE); label.setText("URL:"); GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; label.setLayoutData(gridData); urlText = new Text(composite, SWT.NONE); gridData = new GridData(); gridData.grabExcessHorizontalSpace = true; gridData.horizontalAlignment = GridData.FILL; urlText.setLayoutData(gridData); Button findButton = new Button(composite, SWT.NONE); findButton.setText("..."); findButton.addSelectionListener(new SelectionAdapter(){ public void widgetSelected(SelectionEvent e) { findRepository(); } }); gridData = new GridData(); findButton.setLayoutData(gridData); Button getButton = new Button(composite, SWT.NONE); getButton.setText("Get"); getButton.addSelectionListener(new SelectionAdapter(){ public void widgetSelected(SelectionEvent e) { getWorkDefinitions(); } }); gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; getButton.setLayoutData(gridData); treeViewer = new TreeViewer(composite, SWT.MULTI); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { importButton.setEnabled(!event.getSelection().isEmpty()); if (!event.getSelection().isEmpty()) { Object selected = ((StructuredSelection) event.getSelection()).getFirstElement(); if (selected instanceof WorkDefinitionImpl) { String docs = ((WorkDefinitionImpl) selected).getDocumentation(); if (docs != null) { if (documentation != null) { documentation.setUrl(((WorkDefinitionImpl) selected).getPath() + "/" + docs); } } else { if (documentation != null) { documentation.setText(""); } } } else { if (documentation != null) { documentation.setText(""); } } } } }); treeViewer.setContentProvider(new ITreeContentProvider() { public void inputChanged(Viewer arg0, Object arg1, Object arg2) { } public void dispose() { } public boolean hasChildren(Object object) { if (object instanceof Category) { return !((Category) object).getWorkDefinitions().isEmpty(); } return false; } public Object getParent(Object arg0) { return null; } public Object[] getElements(Object object) { return getChildren(object); } public Object[] getChildren(Object object) { if (object instanceof Collection<?>) { Object[] result = ((Collection<?>) object).toArray(); Arrays.sort(result, new Comparator<Object>() { public int compare(Object o1, Object o2) { return ((Category) o1).name.compareTo(((Category) o2).name); } }); return result; } if (object instanceof Category) { return ((Category) object).getWorkDefinitions().toArray(); } return null; } }); gridData = new GridData(); gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.FILL; gridData.horizontalSpan = 3; treeViewer.getTree().setLayoutData(gridData); importButton = new Button(composite, SWT.NONE); importButton.setText("Import"); gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.verticalAlignment = GridData.BEGINNING; importButton.setLayoutData(gridData); importButton.setEnabled(false); importButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { importWorkDefinitions(); } }); addToConfigFile = new Button(composite, SWT.CHECK | SWT.LEFT); addToConfigFile.setText("Automatically add to service configuration file"); GridData data = new GridData(); data.horizontalSpan = 4; addToConfigFile.setLayoutData(data); addToConfigFile.setSelection(true); addLibraries = new Button(composite, SWT.CHECK | SWT.LEFT); addLibraries.setText("Automatically add libraries to project"); data = new GridData(); data.horizontalSpan = 4; addLibraries.setLayoutData(data); addLibraries.setSelection(true); registerHandlers = new Button(composite, SWT.CHECK | SWT.LEFT); registerHandlers.setText("Automatically register handlers"); data = new GridData(); data.horizontalSpan = 4; registerHandlers.setLayoutData(data); registerHandlers.setSelection(true); try { documentation = new Browser(sashForm, SWT.NONE); } catch (SWTError e) { MessageBox messageBox = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); messageBox.setMessage("Browser cannot be initialized."); messageBox.setText("Exit"); messageBox.open(); } return top; } private void findRepository() { String selectedDirectory = null; String dirName = urlText.getText(); DirectoryDialog dialog = new DirectoryDialog(getShell()); dialog.setMessage("Select the jBPM service repository"); dialog.setFilterPath(dirName); selectedDirectory = dialog.open(); if (selectedDirectory != null) { urlText.setText(selectedDirectory); } } private void getWorkDefinitions() { Map<String, Category> categories = new HashMap<String, Category>(); String url = urlText.getText(); if (!url.startsWith("http") && !url.startsWith("file:")) { url = "file:///" + url; } Map<String, WorkDefinitionImpl> workDefinitions = WorkItemRepository.getWorkDefinitions(url); for (WorkDefinitionImpl workDef: workDefinitions.values()) { String c = workDef.getCategory(); if (c == null) { c = "Other"; } Category category = categories.get(c); if (category == null) { category = new Category(c); categories.put(c, category); } category.addWorkDefinition(workDef); } treeViewer.setInput(categories.values()); } private void importWorkDefinitions() { IFolder folder = project.getProject().getFolder("src/main/resources"); if (!folder.exists()) { folder = project.getProject().getFolder("src/main/rules"); } if (!folder.exists()) { throw new IllegalArgumentException("Could not find src/main/resources folder."); } try { IFolder metaInf = folder.getFolder("META-INF"); if (!metaInf.exists()) { createFolder(metaInf, null); } IFile workDefinitionsConfig = metaInf.getFile("drools.rulebase.conf"); if (addToConfigFile.getSelection() && !workDefinitionsConfig.exists()) { workDefinitionsConfig.create(new ByteArrayInputStream("".getBytes()), true, null); } Iterator<Object> iterator = ((StructuredSelection) treeViewer.getSelection()).iterator(); Map<String, WorkDefinitionImpl> workDefs = new HashMap<String, WorkDefinitionImpl>(); while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof Category) { for (WorkDefinitionImpl workDef: ((Category) o).getWorkDefinitions()) { importWorkDefinition(workDef, folder, metaInf, workDefinitionsConfig); workDefs.put(workDef.getName(), workDef); } } else if (o instanceof WorkDefinitionImpl) { importWorkDefinition((WorkDefinitionImpl) o, folder, metaInf, workDefinitionsConfig); workDefs.put(((WorkDefinitionImpl) o).getName(), (WorkDefinitionImpl) o); } } if (registerHandlers.getSelection()) { IFile sessionConfig = metaInf.getFile("drools.session.conf"); if (!sessionConfig.exists()) { sessionConfig.create(new ByteArrayInputStream("".getBytes()), true, null); } String[] ss = inputStreamContentsToString(sessionConfig.getContents()).split(EOL); String output = ""; boolean found = false; for (String s: ss) { if (!found && s.trim().startsWith("drools.workItemHandlers")) { found = true; if (!s.contains("workItemHandlers.conf")) { s += s + " workItemDefinitions.conf"; } } output += s + EOL; } if (!found) { output += "drools.workItemHandlers = workItemHandlers.conf"; } String newInput = output; sessionConfig.setContents(new ByteArrayInputStream(newInput.getBytes()), true, false, null); IFile workItemHandlersConfig = metaInf.getFile("workItemHandlers.conf"); if (!workItemHandlersConfig.exists()) { String content = "["; for (WorkDefinitionImpl def: workDefs.values()) { if (def.getDefaultHandler() != null) { content += EOL + " \"" + def.getName() + "\" : new " + def.getDefaultHandler().replaceFirst("[^()]+$", "$0()") + ","; } } if (content.endsWith(",")) { content = content.substring(0, content.length() - 1) + EOL + "]"; } workItemHandlersConfig.create(new ByteArrayInputStream(content.getBytes()), true, null); } else { String content = inputStreamContentsToString(workItemHandlersConfig.getContents()).trim(); String newContent = "["; if (content.startsWith("[")) { content = content.substring(1); } for (WorkDefinitionImpl def: workDefs.values()) { if (def.getDefaultHandler() != null) { newContent += EOL + " \"" + def.getName() + "\" : new " + def.getDefaultHandler().replaceFirst("[^()]+$", "$0()") + ","; } } newContent += content; workItemHandlersConfig.setContents(new ByteArrayInputStream(newContent.getBytes()), true, false, null); } } close(); } catch (Throwable t) { throw new IllegalArgumentException("Exception while trying to import services", t); } } private void importWorkDefinition(WorkDefinitionImpl workDef, IFolder resources, IFolder metaInf, IFile workDefinitionsConfig) throws Exception { String defFile = workDef.getPath() + "/" + workDef.getFile(); IFile file = metaInf.getFile(workDef.getFile()); InputStream inputstream = new URL(defFile).openStream(); if (!file.exists()) { file.create(inputstream, true, null); } else { file.setContents(inputstream, true, false, null); } if (workDef.getIcon() != null) { String iconFile = workDef.getPath() + "/" + workDef.getIcon(); IFile icon = resources.getFile(workDef.getIcon()); inputstream = new URL(iconFile).openStream(); if (!icon.exists()) { icon.create(inputstream, true, null); } else { icon.setContents(inputstream, true, false, null); } } if (addToConfigFile.getSelection()) { String[] ss = inputStreamContentsToString(workDefinitionsConfig.getContents()).split(System.getProperty( "line.separator" )); String output = ""; boolean found = false; for (String s: ss) { if (!found && s.trim().startsWith("drools.workDefinitions")) { if (!s.contains(workDef.getFile())) { s += " " + workDef.getFile(); } found = true; } output += s + EOL; } if (!found) { output += EOL + "drools.workDefinitions = " + workDef.getFile(); } String newInput = output; workDefinitionsConfig.setContents(new ByteArrayInputStream(newInput.getBytes()), true, false, null); } String[] dependencies = workDef.getDependencies(); if (addLibraries.getSelection() && dependencies != null) { IFolder lib = project.getProject().getFolder("lib"); if (!lib.exists()) { createFolder(lib, null); } for (String dependency: dependencies) { int index = dependency.indexOf(":"); if (index != -1) { String protocol = dependency.substring(0, index); dependency = dependency.substring(index + 1); if ("file".equals(protocol)) { String libName; index = dependency.lastIndexOf("/"); if (index != -1) { libName = dependency.substring(index + 1); } else { libName = dependency; } if (libName.startsWith("./")) { libName = libName.substring(2); } IFile libFile = lib.getFile(libName); inputstream = new URL(workDef.getPath() + "/" + dependency).openStream(); if (!libFile.exists()) { libFile.create(inputstream, true, null); } else { libFile.setContents(inputstream, true, false, null); } } } } } // TODO: workItemHandler } private void createFolder(IFolder folder, IProgressMonitor monitor) throws CoreException { IContainer container = folder.getParent(); if (container != null && !container.exists() && (container instanceof IFolder)) createFolder((IFolder) container, monitor); if (!folder.exists()) { folder.create(true, true, monitor); } } public static String inputStreamContentsToString(InputStream inputStream) { StringBuilder builder = new StringBuilder(); if ( inputStream == null ) { return null; } try { BufferedReader reader = new BufferedReader(new InputStreamReader( inputStream )); String line = null; while ( ( line = reader.readLine() ) != null ) { // while loop begins here builder.append( line ); builder.append( "\n" ); } reader.close(); } catch ( IOException e ) { throw new RuntimeException( "Unable to read inputstream" ); } return builder.toString(); } private static class Category { private String name; private List<WorkDefinitionImpl> workDefinitions = new ArrayList<WorkDefinitionImpl>(); public Category(String name) { this.name = name; } public String getName() { return name; } public List<WorkDefinitionImpl> getWorkDefinitions() { return workDefinitions; } public void addWorkDefinition(WorkDefinitionImpl workDefinition) { workDefinitions.add(workDefinition); } public String toString() { return name; } } }