001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package com.bostechcorp.cbesb.ui.ide.wizards;
011:
012: import org.eclipse.core.resources.IContainer;
013: import org.eclipse.core.resources.IResource;
014: import org.eclipse.core.resources.IWorkspace;
015: import org.eclipse.core.resources.IWorkspaceRoot;
016: import org.eclipse.core.resources.ResourcesPlugin;
017: import org.eclipse.core.runtime.IPath;
018: import org.eclipse.core.runtime.IStatus;
019: import org.eclipse.core.runtime.Path;
020: import org.eclipse.jface.fieldassist.FieldAssistColors;
021: import org.eclipse.osgi.util.NLS;
022: import org.eclipse.swt.SWT;
023: import org.eclipse.swt.graphics.Font;
024: import org.eclipse.swt.layout.GridData;
025: import org.eclipse.swt.layout.GridLayout;
026: import org.eclipse.swt.widgets.Composite;
027: import org.eclipse.swt.widgets.Event;
028: import org.eclipse.swt.widgets.Label;
029: import org.eclipse.swt.widgets.Listener;
030: import org.eclipse.swt.widgets.Text;
031: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
032: import org.eclipse.ui.internal.ide.misc.ContainerSelectionGroup;
033:
034: /**
035: * Workbench-level composite for resource and container specification by the
036: * user. Services such as field validation are performed by the group. The group
037: * can be configured to accept existing resources, or only new resources.
038: */
039: public class ResourceAndContainerGroup implements Listener {
040: // problem identifiers
041: public static final int PROBLEM_NONE = 0;
042:
043: public static final int PROBLEM_RESOURCE_EMPTY = 1;
044:
045: public static final int PROBLEM_RESOURCE_EXIST = 2;
046:
047: public static final int PROBLEM_RESOURCE_CONTAINS_SEPARATOR = 3;
048:
049: public static final int PROBLEM_PATH_INVALID = 4;
050:
051: public static final int PROBLEM_CONTAINER_EMPTY = 5;
052:
053: public static final int PROBLEM_PROJECT_DOES_NOT_EXIST = 6;
054:
055: public static final int PROBLEM_NAME_INVALID = 7;
056:
057: public static final int PROBLEM_PATH_OCCUPIED = 8;
058:
059: private String prefix = "";
060:
061: // the client to notify of changes
062: private Listener client;
063:
064: // whether to allow existing resources
065: private boolean allowExistingResources = false;
066:
067: // resource type (file, folder, project)
068: private String resourceType = IDEWorkbenchMessages.ResourceGroup_resource;
069:
070: // show closed projects in the tree, by default
071: private boolean showClosedProjects = true;
072:
073: // problem indicator
074: private String problemMessage = "";//$NON-NLS-1$
075:
076: private int problemType = PROBLEM_NONE;
077:
078: // widgets
079: private ContainerSelectionGroup containerGroup;
080:
081: private Text resourceNameField;
082:
083: // constants
084: private static final int SIZING_TEXT_FIELD_WIDTH = 250;
085:
086: /**
087: * Create an instance of the group to allow the user to enter/select a
088: * container and specify a resource name.
089: *
090: * @param parent
091: * composite widget to parent the group
092: * @param client
093: * object interested in changes to the group's fields value
094: * @param resourceFieldLabel
095: * label to use in front of the resource name field
096: * @param resourceType
097: * one word, in lowercase, to describe the resource to the user
098: * (file, folder, project)
099: */
100: public ResourceAndContainerGroup(Composite parent, Listener client,
101: String resourceFieldLabel, String resourceType) {
102: this (parent, client, resourceFieldLabel, resourceType, true);
103: }
104:
105: /**
106: * Create an instance of the group to allow the user to enter/select a
107: * container and specify a resource name.
108: *
109: * @param parent
110: * composite widget to parent the group
111: * @param client
112: * object interested in changes to the group's fields value
113: * @param resourceFieldLabel
114: * label to use in front of the resource name field
115: * @param resourceType
116: * one word, in lowercase, to describe the resource to the user
117: * (file, folder, project)
118: * @param showClosedProjects
119: * whether or not to show closed projects
120: */
121: public ResourceAndContainerGroup(Composite parent, Listener client,
122: String resourceFieldLabel, String resourceType,
123: boolean showClosedProjects) {
124: this (parent, client, resourceFieldLabel, resourceType,
125: showClosedProjects, SWT.DEFAULT);
126: }
127:
128: /**
129: * Create an instance of the group to allow the user to enter/select a
130: * container and specify a resource name.
131: *
132: * @param parent
133: * composite widget to parent the group
134: * @param client
135: * object interested in changes to the group's fields value
136: * @param resourceFieldLabel
137: * label to use in front of the resource name field
138: * @param resourceType
139: * one word, in lowercase, to describe the resource to the user
140: * (file, folder, project)
141: * @param showClosedProjects
142: * whether or not to show closed projects
143: * @param heightHint
144: * height hint for the container selection widget group
145: */
146: public ResourceAndContainerGroup(Composite parent, Listener client,
147: String resourceFieldLabel, String resourceType,
148: boolean showClosedProjects, int heightHint) {
149: super ();
150: this .resourceType = resourceType;
151: this .showClosedProjects = showClosedProjects;
152: createContents(parent, resourceFieldLabel, heightHint);
153: this .client = client;
154: }
155:
156: /**
157: * Returns a boolean indicating whether all controls in this group contain
158: * valid values.
159: *
160: * @return boolean
161: */
162: public boolean areAllValuesValid() {
163: return problemType == PROBLEM_NONE;
164: }
165:
166: /**
167: * Creates this object's visual components.
168: *
169: * @param parent
170: * org.eclipse.swt.widgets.Composite
171: * @param heightHint
172: * height hint for the container selection widget group
173: */
174: protected void createContents(Composite parent,
175: String resourceLabelString, int heightHint) {
176:
177: Font font = parent.getFont();
178: // server name group
179: Composite composite = new Composite(parent, SWT.NONE);
180: GridLayout layout = new GridLayout();
181: layout.marginWidth = 0;
182: layout.marginHeight = 0;
183: composite.setLayout(layout);
184: composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
185: true));
186: composite.setFont(font);
187:
188: // container group
189: if (heightHint == SWT.DEFAULT) {
190: containerGroup = new ContainerSelectionGroup(composite,
191: this , true, null, showClosedProjects);
192: } else {
193: containerGroup = new ContainerSelectionGroup(composite,
194: this , true, null, showClosedProjects, heightHint,
195: SIZING_TEXT_FIELD_WIDTH);
196: }
197:
198: // resource name group
199: Composite nameGroup = new Composite(composite, SWT.NONE);
200: layout = new GridLayout();
201: layout.numColumns = 2;
202: layout.marginWidth = 0;
203: nameGroup.setLayout(layout);
204: nameGroup.setLayoutData(new GridData(
205: GridData.HORIZONTAL_ALIGN_FILL
206: | GridData.GRAB_HORIZONTAL));
207: nameGroup.setFont(font);
208:
209: Label label = new Label(nameGroup, SWT.NONE);
210: label.setText(resourceLabelString);
211: label.setFont(font);
212:
213: // resource name entry field
214: resourceNameField = new Text(nameGroup, SWT.BORDER);
215: resourceNameField.addListener(SWT.Modify, this );
216: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL
217: | GridData.GRAB_HORIZONTAL);
218: data.widthHint = SIZING_TEXT_FIELD_WIDTH;
219: resourceNameField.setLayoutData(data);
220: resourceNameField.setFont(font);
221: resourceNameField.setBackground(FieldAssistColors
222: .getRequiredFieldBackgroundColor(resourceNameField));
223:
224: validateControls();
225: }
226:
227: /**
228: * Returns the path of the currently selected container or null if no
229: * container has been selected. Note that the container may not exist yet if
230: * the user entered a new container name in the field.
231: */
232: public IPath getContainerFullPath() {
233: return containerGroup.getContainerFullPath();
234: }
235:
236: /**
237: * Returns an error message indicating the current problem with the value of
238: * a control in the group, or an empty message if all controls in the group
239: * contain valid values.
240: *
241: * @return java.lang.String
242: */
243: public String getProblemMessage() {
244: return problemMessage;
245: }
246:
247: /**
248: * Returns the type of problem with the value of a control in the group.
249: *
250: * @return one of the PROBLEM_* constants
251: */
252: public int getProblemType() {
253: return problemType;
254: }
255:
256: /**
257: * Returns a string that is the path of the currently selected container.
258: * Returns an empty string if no container has been selected.
259: */
260: public String getResource() {
261: return resourceNameField.getText();
262: }
263:
264: /**
265: * Handles events for all controls in the group.
266: *
267: * @param e
268: * org.eclipse.swt.widgets.Event
269: */
270: public void handleEvent(Event e) {
271: validateControls();
272: if (client != null) {
273: client.handleEvent(e);
274: }
275: }
276:
277: /**
278: * Sets the flag indicating whether existing resources are permitted.
279: */
280: public void setAllowExistingResources(boolean value) {
281: allowExistingResources = value;
282: }
283:
284: /**
285: * Sets the value of this page's container.
286: *
287: * @param path
288: * Full path to the container.
289: */
290: public void setContainerFullPath(IPath path) {
291: IResource initial = ResourcesPlugin.getWorkspace().getRoot()
292: .findMember(path);
293: if (initial != null) {
294: if (!(initial instanceof IContainer)) {
295: initial = initial.getParent();
296: }
297: containerGroup.setSelectedContainer((IContainer) initial);
298: }
299: validateControls();
300: }
301:
302: /**
303: * Gives focus to the resource name field and selects its contents
304: */
305: public void setFocus() {
306: // select the whole resource name.
307: resourceNameField.setSelection(0, resourceNameField.getText()
308: .length());
309: resourceNameField.setFocus();
310: }
311:
312: /**
313: * Sets the value of this page's resource name.
314: *
315: * @param value
316: * new value
317: */
318: public void setResource(String value, String prefix) {
319: this .prefix = prefix;
320: resourceNameField.setText(value);
321: validateControls();
322: }
323:
324: /**
325: * Returns a <code>boolean</code> indicating whether a container name
326: * represents a valid container resource in the workbench. An error message
327: * is stored for future reference if the name does not represent a valid
328: * container.
329: *
330: * @return <code>boolean</code> indicating validity of the container name
331: */
332: protected boolean validateContainer() {
333: IPath path = containerGroup.getContainerFullPath();
334: if (path == null) {
335: problemType = PROBLEM_CONTAINER_EMPTY;
336: problemMessage = IDEWorkbenchMessages.ResourceGroup_folderEmpty;
337: return false;
338: }
339: IWorkspace workspace = ResourcesPlugin.getWorkspace();
340: String projectName = path.segment(0);
341: if (projectName == null
342: || !workspace.getRoot().getProject(projectName)
343: .exists()) {
344: problemType = PROBLEM_PROJECT_DOES_NOT_EXIST;
345: problemMessage = IDEWorkbenchMessages.ResourceGroup_noProject;
346: return false;
347: }
348: // path is invalid if any prefix is occupied by a file
349: IWorkspaceRoot root = workspace.getRoot();
350: while (path.segmentCount() > 1) {
351: if (root.getFile(path).exists()) {
352: problemType = PROBLEM_PATH_OCCUPIED;
353: problemMessage = NLS
354: .bind(
355: IDEWorkbenchMessages.ResourceGroup_pathOccupied,
356: path.makeRelative());
357: return false;
358: }
359: path = path.removeLastSegments(1);
360: }
361: return true;
362: }
363:
364: /**
365: * Validates the values for each of the group's controls. If an invalid
366: * value is found then a descriptive error message is stored for later
367: * reference. Returns a boolean indicating the validity of all of the
368: * controls in the group.
369: */
370: protected boolean validateControls() {
371: // don't attempt to validate controls until they have been created
372: if (containerGroup == null) {
373: return false;
374: }
375: problemType = PROBLEM_NONE;
376: problemMessage = "";//$NON-NLS-1$
377:
378: if (!validateContainer() || !validateResourceName()) {
379: return false;
380: }
381:
382: IPath path = containerGroup.getContainerFullPath().append(
383: resourceNameField.getText() + "." + prefix);
384: return validateFullResourcePath(path);
385: }
386:
387: /**
388: * Returns a <code>boolean</code> indicating whether the specified
389: * resource path represents a valid new resource in the workbench. An error
390: * message is stored for future reference if the path does not represent a
391: * valid new resource path.
392: *
393: * @param resourcePath
394: * the path to validate
395: * @return <code>boolean</code> indicating validity of the resource path
396: */
397: protected boolean validateFullResourcePath(IPath resourcePath) {
398: IWorkspace workspace = ResourcesPlugin.getWorkspace();
399:
400: IStatus result = workspace.validatePath(
401: resourcePath.toString(), IResource.FOLDER);
402: if (!result.isOK()) {
403: problemType = PROBLEM_PATH_INVALID;
404: problemMessage = result.getMessage();
405: return false;
406: }
407:
408: if (!allowExistingResources
409: && (workspace.getRoot().getFolder(resourcePath)
410: .exists() || workspace.getRoot().getFile(
411: resourcePath).exists())) {
412: problemType = PROBLEM_RESOURCE_EXIST;
413: problemMessage = IDEWorkbenchMessages.ResourceGroup_nameExists;
414: return false;
415: }
416: return true;
417: }
418:
419: /**
420: * Returns a <code>boolean</code> indicating whether the resource name
421: * rep- resents a valid resource name in the workbench. An error message is
422: * stored for future reference if the name does not represent a valid
423: * resource name.
424: *
425: * @return <code>boolean</code> indicating validity of the resource name
426: */
427: protected boolean validateResourceName() {
428: String resourceName = resourceNameField.getText();
429:
430: if (resourceName.equals("")) {//$NON-NLS-1$
431: problemType = PROBLEM_RESOURCE_EMPTY;
432: problemMessage = NLS.bind(
433: IDEWorkbenchMessages.ResourceGroup_emptyName,
434: resourceType);
435: return false;
436: }
437:
438: if (!(new Path("")).isValidPath(resourceName)) { //$NON-NLS-1$
439: problemType = PROBLEM_NAME_INVALID;
440: problemMessage = NLS.bind(
441: IDEWorkbenchMessages.ResourceGroup_invalidFilename,
442: resourceName);
443: return false;
444: }
445: return true;
446: }
447:
448: }
|