/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ // AW package org.eclipse.jdt.internal.ui.preferences; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.NoSuchElementException; import java.util.StringTokenizer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Widget; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.JavaConventions; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.internal.ui.dialogs.StatusUtil; /* * The page for defaults for classpath entries in new java projects. * See PreferenceConstants to access or change these values through public API. */ public class NewJavaProjectPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { public static final String ID= "org.eclipse.jdt.ui.preferences.BuildPathPreferencePage"; //$NON-NLS-1$ private static final String SRCBIN_FOLDERS_IN_NEWPROJ= PreferenceConstants.SRCBIN_FOLDERS_IN_NEWPROJ; private static final String SRCBIN_SRCNAME= PreferenceConstants.SRCBIN_SRCNAME; private static final String SRCBIN_BINNAME= PreferenceConstants.SRCBIN_BINNAME; private static final String CLASSPATH_JRELIBRARY_INDEX= PreferenceConstants.NEWPROJECT_JRELIBRARY_INDEX; private static final String CLASSPATH_JRELIBRARY_LIST= PreferenceConstants.NEWPROJECT_JRELIBRARY_LIST; private static String fgDefaultEncoding= System.getProperty("file.encoding"); //$NON-NLS-1$ public static IClasspathEntry[] getDefaultJRELibrary() { IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); String str= store.getString(CLASSPATH_JRELIBRARY_LIST); int index= store.getInt(CLASSPATH_JRELIBRARY_INDEX); StringTokenizer tok= new StringTokenizer(str, ";"); //$NON-NLS-1$ while (tok.hasMoreTokens() && index > 0) { tok.nextToken(); index--; } if (tok.hasMoreTokens()) { IClasspathEntry[] res= decodeJRELibraryClasspathEntries(tok.nextToken()); if (res.length > 0) { return res; } } return new IClasspathEntry[] { getJREContainerEntry() }; } // JRE Entry public static String decodeJRELibraryDescription(String encoded) { int end= encoded.indexOf(' '); if (end != -1) { return decode(encoded.substring(0, end)); } return ""; //$NON-NLS-1$ } private static String decode(String str) { try { return URLDecoder.decode(str, fgDefaultEncoding); } catch (UnsupportedEncodingException e) { JavaPlugin.log(e); } return ""; //$NON-NLS-1$ } private static String encode(String str) { try { return URLEncoder.encode(str, fgDefaultEncoding); } catch (UnsupportedEncodingException e) { JavaPlugin.log(e); } return ""; //$NON-NLS-1$ } public static IClasspathEntry[] decodeJRELibraryClasspathEntries(String encoded) { StringTokenizer tok= new StringTokenizer(encoded, " "); //$NON-NLS-1$ ArrayList<IClasspathEntry> res= new ArrayList<IClasspathEntry>(); while (tok.hasMoreTokens()) { try { tok.nextToken(); // desc: ignore int kind= Integer.parseInt(tok.nextToken()); IPath path= decodePath(tok.nextToken()); IPath attachPath= decodePath(tok.nextToken()); IPath attachRoot= decodePath(tok.nextToken()); boolean isExported= Boolean.valueOf(tok.nextToken()).booleanValue(); switch (kind) { case IClasspathEntry.CPE_SOURCE: res.add(JavaCore.newSourceEntry(path)); break; case IClasspathEntry.CPE_LIBRARY: res.add(JavaCore.newLibraryEntry(path, attachPath, attachRoot, isExported)); break; case IClasspathEntry.CPE_VARIABLE: res.add(JavaCore.newVariableEntry(path, attachPath, attachRoot, isExported)); break; case IClasspathEntry.CPE_PROJECT: res.add(JavaCore.newProjectEntry(path, isExported)); break; case IClasspathEntry.CPE_CONTAINER: res.add(JavaCore.newContainerEntry(path, isExported)); break; } } catch (NumberFormatException e) { String message= PreferencesMessages.NewJavaProjectPreferencePage_error_decode; JavaPlugin.log(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, message, e)); } catch (NoSuchElementException e) { String message= PreferencesMessages.NewJavaProjectPreferencePage_error_decode; JavaPlugin.log(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, IStatus.ERROR, message, e)); } } return res.toArray(new IClasspathEntry[res.size()]); } public static String encodeJRELibrary(String desc, IClasspathEntry[] cpentries) { StringBuffer buf= new StringBuffer(); for (int i= 0; i < cpentries.length; i++) { IClasspathEntry entry= cpentries[i]; buf.append(encode(desc)); buf.append(' '); buf.append(entry.getEntryKind()); buf.append(' '); buf.append(encodePath(entry.getPath())); buf.append(' '); buf.append(encodePath(entry.getSourceAttachmentPath())); buf.append(' '); buf.append(encodePath(entry.getSourceAttachmentRootPath())); buf.append(' '); buf.append(entry.isExported()); buf.append(' '); } return buf.toString(); } private static String encodePath(IPath path) { if (path == null) { return "#"; //$NON-NLS-1$ } else if (path.isEmpty()) { return "&"; //$NON-NLS-1$ } else { return encode(path.toPortableString()); } } private static IPath decodePath(String str) { if ("#".equals(str)) { //$NON-NLS-1$ return null; } else if ("&".equals(str)) { //$NON-NLS-1$ return Path.EMPTY; } else { return Path.fromPortableString(decode(str)); } } private ArrayList<Button> fCheckBoxes; private ArrayList<Button> fRadioButtons; private ArrayList<Text> fTextControls; private SelectionListener fSelectionListener; private ModifyListener fModifyListener; private Text fBinFolderNameText; private Text fSrcFolderNameText; private Combo fJRECombo; private Button fProjectAsSourceFolder; private Button fFoldersAsSourceFolder; private Label fSrcFolderNameLabel; private Label fBinFolderNameLabel; public NewJavaProjectPreferencePage() { super(); setPreferenceStore(JavaPlugin.getDefault().getPreferenceStore()); setDescription(PreferencesMessages.NewJavaProjectPreferencePage_description); // title used when opened programatically setTitle(PreferencesMessages.NewJavaProjectPreferencePage_title); fRadioButtons= new ArrayList<Button>(); fCheckBoxes= new ArrayList<Button>(); fTextControls= new ArrayList<Text>(); fSelectionListener= new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) {} public void widgetSelected(SelectionEvent e) { controlChanged(e.widget); } }; fModifyListener= new ModifyListener() { public void modifyText(ModifyEvent e) { controlModified(e.widget); } }; } public static void initDefaults(IPreferenceStore store) { store.setDefault(SRCBIN_FOLDERS_IN_NEWPROJ, true); store.setDefault(SRCBIN_SRCNAME, "src"); //$NON-NLS-1$ store.setDefault(SRCBIN_BINNAME, "bin"); //$NON-NLS-1$ store.setDefault(CLASSPATH_JRELIBRARY_LIST, getDefaultJRELibraries()); store.setDefault(CLASSPATH_JRELIBRARY_INDEX, 0); } private static String getDefaultJRELibraries() { StringBuffer buf= new StringBuffer(); IClasspathEntry cntentry= getJREContainerEntry(); buf.append(encodeJRELibrary(PreferencesMessages.NewJavaProjectPreferencePage_jre_container_description, new IClasspathEntry[] { cntentry} )); buf.append(';'); IClasspathEntry varentry= getJREVariableEntry(); buf.append(encodeJRELibrary(PreferencesMessages.NewJavaProjectPreferencePage_jre_variable_description, new IClasspathEntry[] { varentry })); buf.append(';'); return buf.toString(); } private static IClasspathEntry getJREContainerEntry() { return JavaCore.newContainerEntry(new Path("org.eclipse.jdt.launching.JRE_CONTAINER")); //$NON-NLS-1$ } private static IClasspathEntry getJREVariableEntry() { return JavaCore.newVariableEntry(new Path("JRE_LIB"), new Path("JRE_SRC"), new Path("JRE_SRCROOT")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } /* * @see IWorkbenchPreferencePage#init(IWorkbench) */ public void init(IWorkbench workbench) { } /** * @see PreferencePage#createControl(Composite) */ @Override public void createControl(Composite parent) { super.createControl(parent); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.NEW_JAVA_PROJECT_PREFERENCE_PAGE); } private Button addRadioButton(Composite parent, String label, String key, String value, int indent) { GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd.horizontalSpan= 2; gd.horizontalIndent= indent; Button button= new Button(parent, SWT.RADIO); button.setText(label); button.setData(new String[] { key, value }); button.setLayoutData(gd); button.setSelection(value.equals(getPreferenceStore().getString(key))); fRadioButtons.add(button); return button; } private Text addTextControl(Composite parent, Label labelControl, String key, int indent) { GridData gd= new GridData(); gd.horizontalIndent= indent; labelControl.setLayoutData(gd); gd= new GridData(GridData.FILL_HORIZONTAL); gd.widthHint= convertWidthInCharsToPixels(30); Text text= new Text(parent, SWT.SINGLE | SWT.BORDER); text.setText(getPreferenceStore().getString(key)); text.setData(key); text.setLayoutData(gd); fTextControls.add(text); return text; } @Override protected Control createContents(Composite parent) { initializeDialogUnits(parent); Composite result= new Composite(parent, SWT.NONE); GridLayout layout= new GridLayout(); layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); layout.marginWidth= 0; layout.verticalSpacing= convertVerticalDLUsToPixels(10); layout.horizontalSpacing= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); layout.numColumns= 2; result.setLayout(layout); GridData gd= new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan= 2; Group sourceFolderGroup= new Group(result, SWT.NONE); layout= new GridLayout(); layout.numColumns= 2; sourceFolderGroup.setLayout(layout); sourceFolderGroup.setLayoutData(gd); sourceFolderGroup.setText(PreferencesMessages.NewJavaProjectPreferencePage_sourcefolder_label); int indent= 0; fProjectAsSourceFolder= addRadioButton(sourceFolderGroup, PreferencesMessages.NewJavaProjectPreferencePage_sourcefolder_project, SRCBIN_FOLDERS_IN_NEWPROJ, IPreferenceStore.FALSE, indent); fProjectAsSourceFolder.addSelectionListener(fSelectionListener); fFoldersAsSourceFolder= addRadioButton(sourceFolderGroup, PreferencesMessages.NewJavaProjectPreferencePage_sourcefolder_folder, SRCBIN_FOLDERS_IN_NEWPROJ, IPreferenceStore.TRUE, indent); fFoldersAsSourceFolder.addSelectionListener(fSelectionListener); indent= convertWidthInCharsToPixels(4); fSrcFolderNameLabel= new Label(sourceFolderGroup, SWT.NONE); fSrcFolderNameLabel.setText(PreferencesMessages.NewJavaProjectPreferencePage_folders_src); fSrcFolderNameText= addTextControl(sourceFolderGroup, fSrcFolderNameLabel, SRCBIN_SRCNAME, indent); fSrcFolderNameText.addModifyListener(fModifyListener); fBinFolderNameLabel= new Label(sourceFolderGroup, SWT.NONE); fBinFolderNameLabel.setText(PreferencesMessages.NewJavaProjectPreferencePage_folders_bin); fBinFolderNameText= addTextControl(sourceFolderGroup, fBinFolderNameLabel, SRCBIN_BINNAME, indent); fBinFolderNameText.addModifyListener(fModifyListener); String[] jreNames= getJRENames(); if (jreNames.length > 0) { Label jreSelectionLabel= new Label(result, SWT.NONE); jreSelectionLabel.setText(PreferencesMessages.NewJavaProjectPreferencePage_jrelibrary_label); jreSelectionLabel.setLayoutData(new GridData()); int index= getPreferenceStore().getInt(CLASSPATH_JRELIBRARY_INDEX); fJRECombo= new Combo(result, SWT.READ_ONLY); fJRECombo.setItems(jreNames); fJRECombo.select(index); fJRECombo.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); } validateFolders(); Dialog.applyDialogFont(result); return result; } private void validateFolders() { boolean useFolders= fFoldersAsSourceFolder.getSelection(); fSrcFolderNameText.setEnabled(useFolders); fBinFolderNameText.setEnabled(useFolders); fSrcFolderNameLabel.setEnabled(useFolders); fBinFolderNameLabel.setEnabled(useFolders); if (useFolders) { String srcName= fSrcFolderNameText.getText(); String binName= fBinFolderNameText.getText(); if (srcName.length() + binName.length() == 0) { updateStatus(new StatusInfo(IStatus.ERROR, PreferencesMessages.NewJavaProjectPreferencePage_folders_error_namesempty)); return; } IWorkspace workspace= JavaPlugin.getWorkspace(); IProject dmy= workspace.getRoot().getProject("project"); //$NON-NLS-1$ IStatus status; IPath srcPath= dmy.getFullPath().append(srcName); if (srcName.length() != 0) { status= workspace.validatePath(srcPath.toString(), IResource.FOLDER); if (!status.isOK()) { String message= Messages.format(PreferencesMessages.NewJavaProjectPreferencePage_folders_error_invalidsrcname, status.getMessage()); updateStatus(new StatusInfo(IStatus.ERROR, message)); return; } } IPath binPath= dmy.getFullPath().append(binName); if (binName.length() != 0) { status= workspace.validatePath(binPath.toString(), IResource.FOLDER); if (!status.isOK()) { String message= Messages.format(PreferencesMessages.NewJavaProjectPreferencePage_folders_error_invalidbinname, status.getMessage()); updateStatus(new StatusInfo(IStatus.ERROR, message)); return; } } IClasspathEntry entry= JavaCore.newSourceEntry(srcPath); status= JavaConventions.validateClasspath(JavaCore.create(dmy), new IClasspathEntry[] { entry }, binPath); if (!status.isOK()) { String message= PreferencesMessages.NewJavaProjectPreferencePage_folders_error_invalidcp; updateStatus(new StatusInfo(IStatus.ERROR, message)); return; } } updateStatus(new StatusInfo()); // set to OK } private void updateStatus(IStatus status) { setValid(!status.matches(IStatus.ERROR)); StatusUtil.applyToStatusLine(this, status); } private void controlChanged(Widget widget) { if (widget == fFoldersAsSourceFolder || widget == fProjectAsSourceFolder) { validateFolders(); } } private void controlModified(Widget widget) { if (widget == fSrcFolderNameText || widget == fBinFolderNameText) { validateFolders(); } } /* * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { IPreferenceStore store= getPreferenceStore(); for (int i= 0; i < fCheckBoxes.size(); i++) { Button button= fCheckBoxes.get(i); String key= (String) button.getData(); button.setSelection(store.getDefaultBoolean(key)); } for (int i= 0; i < fRadioButtons.size(); i++) { Button button= fRadioButtons.get(i); String[] info= (String[]) button.getData(); button.setSelection(info[1].equals(store.getDefaultString(info[0]))); } for (int i= 0; i < fTextControls.size(); i++) { Text text= fTextControls.get(i); String key= (String) text.getData(); text.setText(store.getDefaultString(key)); } if (fJRECombo != null) { fJRECombo.select(store.getDefaultInt(CLASSPATH_JRELIBRARY_INDEX)); } validateFolders(); super.performDefaults(); } /* * @see IPreferencePage#performOk() */ @Override public boolean performOk() { IPreferenceStore store= getPreferenceStore(); for (int i= 0; i < fCheckBoxes.size(); i++) { Button button= fCheckBoxes.get(i); String key= (String) button.getData(); store.setValue(key, button.getSelection()); } for (int i= 0; i < fRadioButtons.size(); i++) { Button button= fRadioButtons.get(i); if (button.getSelection()) { String[] info= (String[]) button.getData(); store.setValue(info[0], info[1]); } } for (int i= 0; i < fTextControls.size(); i++) { Text text= fTextControls.get(i); String key= (String) text.getData(); store.setValue(key, text.getText()); } if (fJRECombo != null) { store.setValue(CLASSPATH_JRELIBRARY_INDEX, fJRECombo.getSelectionIndex()); } JavaPlugin.flushInstanceScope(); return super.performOk(); } private String[] getJRENames() { String prefString= getPreferenceStore().getString(CLASSPATH_JRELIBRARY_LIST); ArrayList<String> list= new ArrayList<String>(); StringTokenizer tok= new StringTokenizer(prefString, ";"); //$NON-NLS-1$ while (tok.hasMoreTokens()) { list.add(decodeJRELibraryDescription(tok.nextToken())); } return list.toArray(new String[list.size()]); } }