001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package org.terracotta.dso.dialogs;
006:
007: import org.eclipse.jface.dialogs.IDialogConstants;
008: import org.eclipse.jface.dialogs.MessageDialog;
009: import org.eclipse.swt.SWT;
010: import org.eclipse.swt.custom.CLabel;
011: import org.eclipse.swt.events.FocusAdapter;
012: import org.eclipse.swt.events.FocusEvent;
013: import org.eclipse.swt.events.MouseEvent;
014: import org.eclipse.swt.events.MouseMoveListener;
015: import org.eclipse.swt.events.SelectionAdapter;
016: import org.eclipse.swt.events.SelectionEvent;
017: import org.eclipse.swt.events.SelectionListener;
018: import org.eclipse.swt.graphics.Point;
019: import org.eclipse.swt.layout.GridData;
020: import org.eclipse.swt.layout.GridLayout;
021: import org.eclipse.swt.widgets.Button;
022: import org.eclipse.swt.widgets.Combo;
023: import org.eclipse.swt.widgets.Composite;
024: import org.eclipse.swt.widgets.Control;
025: import org.eclipse.swt.widgets.DirectoryDialog;
026: import org.eclipse.swt.widgets.Label;
027: import org.eclipse.swt.widgets.Shell;
028: import org.eclipse.swt.widgets.Table;
029: import org.eclipse.swt.widgets.TableColumn;
030: import org.eclipse.swt.widgets.TableItem;
031: import org.terracotta.ui.util.SWTUtil;
032:
033: import com.terracottatech.config.Module;
034: import com.terracottatech.config.Modules;
035:
036: import java.io.File;
037: import java.io.FilenameFilter;
038: import java.net.MalformedURLException;
039: import java.net.URL;
040: import java.util.ArrayList;
041: import java.util.Arrays;
042: import java.util.Comparator;
043:
044: public class NewAddModuleDialog extends MessageDialog {
045: private Modules fModules;
046: private Combo fGroupIdCombo;
047: private static ArrayList<String> fCachedGroupIds = new ArrayList<String>();
048: private Table fTable;
049: private SelectionListener fColumnSelectionListener;
050: private CLabel fPathLabel;
051: private Button fAddRepoButton;
052:
053: private ValueListener m_valueListener;
054:
055: private static final String GROUP_ID = "Group Identifier:";
056: private static final String REPO = "Repository";
057: private static final String NAME = "Name";
058: private static final String VERSION = "Version";
059:
060: private static final String VERSION_PATTERN = "^[0-9]+\\.[0-9]+\\.[0-9]+(-SNAPSHOT)?$";
061:
062: public NewAddModuleDialog(Shell parentShell, String title,
063: String message, Modules modules) {
064: super (parentShell, "Select modules", null,
065: "Select modules to add to your configuration",
066: MessageDialog.NONE, new String[] {
067: IDialogConstants.OK_LABEL,
068: IDialogConstants.CANCEL_LABEL }, 0);
069: setShellStyle(SWT.DIALOG_TRIM | getDefaultOrientation()
070: | SWT.RESIZE);
071: fModules = modules != null ? (Modules) modules.copy()
072: : Modules.Factory.newInstance();
073: fColumnSelectionListener = new ColumnSelectionListener();
074: }
075:
076: protected Control createCustomArea(Composite parent) {
077: Composite comp = new Composite(parent, SWT.NONE);
078: comp.setLayout(new GridLayout());
079: comp.setLayoutData(new GridData(GridData.FILL_BOTH));
080:
081: Composite groupComp = new Composite(comp, SWT.NONE);
082: groupComp.setLayout(new GridLayout(2, false));
083:
084: Label groupIdLabel = new Label(groupComp, SWT.NONE);
085: groupIdLabel.setText(GROUP_ID);
086: groupIdLabel.setLayoutData(new GridData());
087:
088: fGroupIdCombo = new Combo(groupComp, SWT.BORDER);
089: fGroupIdCombo.setLayoutData(new GridData(
090: GridData.FILL_HORIZONTAL));
091: fGroupIdCombo.add("org.terracotta.modules");
092: for (String groupId : fCachedGroupIds.toArray(new String[0])) {
093: fGroupIdCombo.add(groupId);
094: }
095: fGroupIdCombo.select(0);
096: fGroupIdCombo.addSelectionListener(new SelectionAdapter() {
097: public void widgetSelected(SelectionEvent e) {
098: populateTable();
099: }
100: });
101: fGroupIdCombo.addFocusListener(new FocusAdapter() {
102: public void focusLost(FocusEvent e) {
103: String text = fGroupIdCombo.getText();
104: if (fGroupIdCombo.indexOf(text) == -1) {
105: fGroupIdCombo.add(text);
106: fCachedGroupIds.add(text);
107: }
108: populateTable();
109: }
110: });
111:
112: fTable = new Table(comp, SWT.BORDER | SWT.MULTI
113: | SWT.FULL_SELECTION | SWT.V_SCROLL);
114: fTable.setHeaderVisible(true);
115: fTable.setLinesVisible(true);
116: GridData gridData = new GridData(GridData.FILL_BOTH);
117: gridData.heightHint = SWTUtil.tableRowsToPixels(fTable, 10);
118: gridData.widthHint = SWTUtil.textColumnsToPixels(fTable, 100);
119: fTable.setLayoutData(gridData);
120:
121: TableColumn column0 = new TableColumn(fTable, SWT.NONE);
122: column0.setResizable(true);
123: column0.setText(REPO);
124: column0.pack();
125: column0.addSelectionListener(fColumnSelectionListener);
126:
127: TableColumn column1 = new TableColumn(fTable, SWT.NONE);
128: column1.setResizable(true);
129: column1.setText(NAME);
130: column1.pack();
131: column1.addSelectionListener(fColumnSelectionListener);
132:
133: TableColumn column2 = new TableColumn(fTable, SWT.NONE);
134: column2.setResizable(true);
135: column2.setText(VERSION);
136: column2.pack();
137: column2.addSelectionListener(fColumnSelectionListener);
138:
139: SWTUtil.makeTableColumnsResizeWeightedWidth(comp, fTable,
140: new int[] { 2, 2, 1 });
141:
142: fTable.addMouseMoveListener(new MouseMoveListener() {
143: public void mouseMove(MouseEvent e) {
144: String tip = null;
145: TableItem item = fTable.getItem(new Point(e.x, e.y));
146: if (item != null) {
147: ItemData itemData = (ItemData) item.getData();
148: tip = itemData.fArchiveFile.getAbsolutePath();
149: }
150: fPathLabel.setText(tip);
151: }
152: });
153:
154: populateTable();
155:
156: fPathLabel = new CLabel(comp, SWT.NONE);
157: fPathLabel
158: .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
159:
160: fAddRepoButton = new Button(comp, SWT.PUSH);
161: fAddRepoButton.setText("Add repository...");
162: fAddRepoButton.setLayoutData(new GridData());
163: fAddRepoButton.addSelectionListener(new SelectionAdapter() {
164: public void widgetSelected(SelectionEvent e) {
165: DirectoryDialog directoryDialog = new DirectoryDialog(
166: getShell());
167: directoryDialog
168: .setText("Terracotta Module Repository Chooser");
169: directoryDialog
170: .setMessage("Select a module repository directory");
171: String path = directoryDialog.open();
172: if (path != null) {
173: File dir = new File(path);
174: try {
175: fModules.addRepository(dir.toURL().toString());
176: populateTable();
177: } catch (MalformedURLException mure) {/**/
178: }
179: }
180: }
181: });
182:
183: return comp;
184: }
185:
186: private void populateTable() {
187: fTable.removeAll();
188: File installRoot = new File(System
189: .getProperty("tc.install-root"));
190: populateTable(new File(installRoot, "modules"), "KIT");
191: String[] repos = fModules.getRepositoryArray();
192: if (repos != null) {
193: for (String repo : repos) {
194: try {
195: File repoDir = new File(new URL(repo).getFile());
196: if (repoDir.exists() && repoDir.isDirectory()) {
197: populateTable(repoDir, null);
198: }
199: } catch (MalformedURLException e) {/**/
200: }
201: }
202: }
203: }
204:
205: private void populateTable(File repoDir, String nickname) {
206: File groupDir = new File(repoDir, fGroupIdCombo.getText()
207: .replace('.', File.separatorChar));
208: File[] names = groupDir.listFiles();
209:
210: if (names == null)
211: return;
212:
213: for (File nameFile : names) {
214: File[] versions = nameFile.listFiles(new FilenameFilter() {
215: public boolean accept(File dir, String name) {
216: return name.matches(VERSION_PATTERN);
217: }
218: });
219: if (versions == null)
220: continue;
221: for (File versionFile : versions) {
222: TableItem item = new TableItem(fTable, SWT.NONE);
223: String repo = nickname != null ? nickname : repoDir
224: .getAbsolutePath();
225: String name = nameFile.getName();
226: String version = versionFile.getName();
227: String[] strings = new String[] { repo, name, version };
228: item.setText(strings);
229: File archiveFile = new File(versionFile, name + "-"
230: + version + ".jar");
231: item
232: .setData(new ItemData(strings, repoDir,
233: archiveFile));
234: }
235: }
236: }
237:
238: class ColumnSelectionListener extends SelectionAdapter {
239: public void widgetSelected(SelectionEvent e) {
240: TableColumn col = (TableColumn) e.widget;
241: switch (fTable.getSortDirection()) {
242: case SWT.DOWN:
243: fTable.setSortDirection(SWT.UP);
244: break;
245: case SWT.UP:
246: default:
247: fTable.setSortDirection(SWT.DOWN);
248: }
249: fTable.setSortColumn(col);
250: sort();
251: }
252: }
253:
254: void sort() {
255: int itemCount = fTable.getItemCount();
256: if (itemCount == 0 || itemCount == 1)
257: return;
258: Comparator<ItemData> comparator = new Comparator<ItemData>() {
259: final int sortDirection = fTable.getSortDirection();
260: final TableColumn sortColumn = fTable.getSortColumn();
261: int index = sortColumn == null ? 0 : fTable
262: .indexOf(sortColumn);
263:
264: public int compare(ItemData itemData1, ItemData itemData2) {
265: if (sortDirection == SWT.UP
266: || sortDirection == SWT.NONE) {
267: return itemData1.fStrings[index]
268: .compareTo(itemData2.fStrings[index]);
269: } else {
270: return itemData2.fStrings[index]
271: .compareTo(itemData1.fStrings[index]);
272: }
273: }
274: };
275: ArrayList<ItemData> selection = new ArrayList<ItemData>();
276: for (TableItem item : fTable.getSelection()) {
277: selection.add((ItemData) item.getData());
278: }
279: ItemData[] data = new ItemData[fTable.getItemCount()];
280: for (int i = 0; i < fTable.getItemCount(); i++) {
281: data[i] = (ItemData) (fTable.getItem(i).getData());
282: }
283: Arrays.sort(data, 0, itemCount, comparator);
284: fTable.setRedraw(false);
285: try {
286: fTable.deselectAll();
287: for (int i = 0; i < fTable.getItemCount(); i++) {
288: TableItem item = fTable.getItem(i);
289: ItemData itemData = data[i];
290: item.setText(itemData.fStrings);
291: item.setData(itemData);
292: if (selection.contains(itemData)) {
293: fTable.select(i);
294: }
295: }
296: } finally {
297: fTable.setRedraw(true);
298: }
299: }
300:
301: protected void buttonPressed(int buttonId) {
302: if (buttonId == IDialogConstants.OK_ID) {
303: TableItem[] items = fTable.getSelection();
304: String groupId = fGroupIdCombo.getText();
305:
306: for (TableItem item : items) {
307: Module module = fModules.addNewModule();
308: module.setGroupId(groupId);
309: module.setName(item.getText(1).replace('-', '_'));
310: module.setVersion(item.getText(2).replace('-', '.'));
311: }
312: if (m_valueListener != null)
313: m_valueListener.setValue(fModules);
314: }
315: super .buttonPressed(buttonId);
316: }
317:
318: class ItemData {
319: String[] fStrings;
320: File fRepoDir;
321: File fArchiveFile;
322:
323: ItemData(String[] strings, File repoDir, File moduleFile) {
324: fStrings = strings;
325: fRepoDir = repoDir;
326: fArchiveFile = moduleFile;
327: }
328: }
329:
330: public void addValueListener(ValueListener listener) {
331: this .m_valueListener = listener;
332: }
333:
334: // --------------------------------------------------------------------------------
335:
336: public static interface ValueListener {
337: void setValue(Modules modules);
338: }
339: }
|