001/*
002  GRANITE DATA SERVICES
003  Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004
005  This file is part of Granite Data Services.
006
007  Granite Data Services is free software; you can redistribute it and/or modify
008  it under the terms of the GNU Library General Public License as published by
009  the Free Software Foundation; either version 2 of the License, or (at your
010  option) any later version.
011
012  Granite Data Services is distributed in the hope that it will be useful, but
013  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015  for more details.
016
017  You should have received a copy of the GNU Library General Public License
018  along with this library; if not, see <http://www.gnu.org/licenses/>.
019*/
020
021package org.granite.builder.ui;
022
023import java.io.File;
024import java.util.ArrayList;
025import java.util.List;
026
027import org.eclipse.core.runtime.CoreException;
028import org.eclipse.swt.SWT;
029import org.eclipse.swt.events.SelectionAdapter;
030import org.eclipse.swt.events.SelectionEvent;
031import org.eclipse.swt.graphics.Rectangle;
032import org.eclipse.swt.layout.FillLayout;
033import org.eclipse.swt.layout.GridData;
034import org.eclipse.swt.layout.GridLayout;
035import org.eclipse.swt.widgets.Button;
036import org.eclipse.swt.widgets.Composite;
037import org.eclipse.swt.widgets.DirectoryDialog;
038import org.eclipse.swt.widgets.FileDialog;
039import org.eclipse.swt.widgets.Label;
040import org.eclipse.swt.widgets.Tree;
041import org.eclipse.swt.widgets.TreeItem;
042import org.granite.builder.GraniteBuilderContext;
043import org.granite.builder.properties.Gas3Classpath;
044import org.granite.builder.properties.GraniteProperties;
045import org.granite.builder.util.ProjectUtil;
046import org.granite.builder.util.SWTUtil;
047import org.granite.builder.util.ProjectUtil.CpEntry;
048
049/**
050 * @author Franck WOLFF
051 */
052public class ClasspathsPanel extends Composite {
053
054        private final GraniteBuilderContext context;
055        private final GraniteProperties properties;
056        
057        private Tree classpathsTree = null;
058        private boolean initialized = false;
059
060        public ClasspathsPanel(Composite parent, GraniteBuilderContext context) throws CoreException {
061        super(parent, SWT.NONE);
062        this.context = context;
063        this.properties = context.getProperties();
064        initializeComponents();
065        }
066
067        public List<Gas3Classpath> getClasspaths() {
068                if (!initialized)
069                        return properties.getGas3().getClasspaths();
070                
071                List<Gas3Classpath> classpaths = new ArrayList<Gas3Classpath>(classpathsTree.getItemCount() - 1);
072                for (int i = 1; i < classpathsTree.getItemCount(); i++) {
073                        TreeItem item = classpathsTree.getItem(i);
074                        classpaths.add(new Gas3Classpath((String)item.getData()));
075                }
076                return classpaths;
077        }
078
079        @Override
080        public Rectangle getClientArea() {
081                initializeContent();
082                return super.getClientArea();
083        }
084
085        private void initializeContent() {
086                if (!initialized) {
087                        try {
088                        TreeItem projectItem = SWTUtil.addTreeItem(classpathsTree, SWTUtil.IMG_PKG_FOLDER, "Project classpath (can't be removed)", null, null);
089
090                        // Output locations.
091                        List<CpEntry> cpEntries = ProjectUtil.getFullClasspath(context.getJavaProject());
092                        for (CpEntry entry : cpEntries) {
093                                if (entry.getKind() == CpEntry.CpeKind.SOURCE_OUTPUT_DIR || entry.getKind() == CpEntry.CpeKind.PROJECT_OUTPUT_DIR)
094                                        SWTUtil.addTreeItem(projectItem, SWTUtil.IMG_PKG_FOLDER, entry.getDescription(), null, null);
095                        }
096
097                        // Project jars.
098                        for (CpEntry entry : cpEntries) {
099                                if (entry.getKind() == CpEntry.CpeKind.LIB_JAR)
100                                        SWTUtil.addTreeItem(projectItem, SWTUtil.IMG_JAR, entry.getDescription(), null, null);
101                        }
102
103                        // Containers jars.
104                        for (CpEntry entry : cpEntries) {
105                                if (entry.getKind() == CpEntry.CpeKind.CONTAINER_JAR) {
106                                TreeItem jreItem = SWTUtil.addTreeItem(projectItem, SWTUtil.IMG_LIBRARY, entry.getDescription(), null, null);
107                                for (CpEntry cEntry : entry.getChildren())
108                                        SWTUtil.addTreeItem(jreItem, SWTUtil.IMG_JAR_LIBRARY, cEntry.getDescription(), null, null);
109                                }
110                        }
111
112                        // Added jars.
113                        for (Gas3Classpath classpath : properties.getGas3().getClasspaths()) {
114                                File path = new File(classpath.getPath());
115                                        TreeItem item;
116                                if (!path.exists())
117                                        item = SWTUtil.addTreeItem(classpathsTree, SWTUtil.IMG_WARNING, classpath.getPath(), null, null);
118                                else if (path.isDirectory())
119                                        item = SWTUtil.addTreeItem(classpathsTree, SWTUtil.IMG_PKG_FOLDER, classpath.getPath(), null, null);
120                                else {
121                                                String label = path.getName();
122                                                if (path.getParent() != null)
123                                                        label += " - " + path.getParent().toString();
124                                                item = SWTUtil.addTreeItem(classpathsTree, SWTUtil.IMG_JAR, label, null, null);
125                                        }
126                                        item.setData(classpath.getPath());
127                        }
128                        } catch (CoreException e) {
129                                throw new RuntimeException(e);
130                        }
131                        initialized = true;
132                }
133        }
134        
135        private void initializeComponents() {
136        setLayout(new GridLayout(2, false));
137        
138        Label text = new Label(this, SWT.NONE);
139        text.setText("Jars and class folders on the classpath:");
140        text.setLayoutData(SWTUtil.newGridData(SWT.NONE, 2));
141        
142        classpathsTree = new Tree(this, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
143        classpathsTree.setLayoutData(new GridData(
144            GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL |
145            GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL
146        ));
147        
148                
149                Composite buttons = new Composite(this, SWT.NONE);
150                buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
151                buttons.setLayout(new FillLayout(SWT.VERTICAL));
152                
153                SWTUtil.newButton(buttons, "Add Jar...", true, new SelectionAdapter() {
154
155                        @Override
156                        public void widgetSelected(SelectionEvent e) {
157                                FileDialog dlg = new FileDialog(e.display.getActiveShell(), SWT.OPEN | SWT.MULTI);
158                                dlg.setFilterPath(context.getJavaProject().getProject().getLocation().toString());
159                            dlg.setText("Jar File Dialog");
160                            dlg.setFilterExtensions(new String[]{"*.jar", "*.zip"});
161
162                                dlg.open();
163
164                                for (String jar : dlg.getFileNames()) {
165                                        TreeItem item = SWTUtil.addTreeItem(classpathsTree, SWTUtil.IMG_JAR, jar + " - " + dlg.getFilterPath(), null, null);
166                                        item.setData(dlg.getFilterPath() + File.separatorChar + jar);
167                                }
168                        }
169                });
170                
171                SWTUtil.newButton(buttons, "Add Folder...", true, new SelectionAdapter() {
172
173                        @Override
174                        public void widgetSelected(SelectionEvent e) {
175                                DirectoryDialog dlg = new DirectoryDialog(e.display.getActiveShell());
176                                dlg.setFilterPath(context.getJavaProject().getProject().getLocation().toString());
177                            dlg.setText("Class Folder Dialog");
178                            dlg.setMessage("Select a class folder to add");
179                                
180                            String dir = dlg.open();
181                                
182                            if (dir != null) {
183                                TreeItem item = SWTUtil.addTreeItem(classpathsTree, SWTUtil.IMG_PKG_FOLDER, dir, null, null);
184                                item.setData(dir);
185                            }
186                        }
187                });
188                
189                final Button removeButton = SWTUtil.newButton(buttons, "Remove", false, new SelectionAdapter() {
190                        
191                        @Override
192                        public void widgetSelected(SelectionEvent e) {
193                                // Remove selected root items.
194                                for (TreeItem item : classpathsTree.getSelection()) {
195                                        if (item.getParentItem() == null && !item.equals(classpathsTree.getItem(0)))
196                                                item.dispose();
197                                }
198                        }
199                });
200                
201                classpathsTree.addSelectionListener(new SelectionAdapter() {
202                        @Override
203                        public void widgetSelected(SelectionEvent e) {
204                                // Enable/Disable buttons based on selected tree items.
205                                boolean removeEnabled = classpathsTree.getSelectionCount() > 0;
206                                for (TreeItem item : classpathsTree.getSelection()) {
207                                        while (item.getParentItem() != null)
208                                                item = item.getParentItem();
209                                        if (item.equals(classpathsTree.getItem(0))) {
210                                                removeEnabled = false;
211                                                break;
212                                        }
213                                }
214                                removeButton.setEnabled(removeEnabled);
215                        }
216                });
217        }
218}