| /******************************************************************************* |
| * Copyright (c) 2000, 2016 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 |
| * |
| * This is an implementation of an early-draft specification developed under the Java |
| * Community Process (JCP) and is made available for testing and evaluation purposes |
| * only. The code is not compatible with any specification of the JCP. |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Philippe Marschall <philippe.marschall@netcetera.ch> - [type wizards] Allow the creation of a compilation unit called package-info.java - https://bugs.eclipse.org/86168 |
| * Michael Pellaton <michael.pellaton@netcetera.ch> - [type wizards] Allow the creation of a compilation unit called package-info.java - https://bugs.eclipse.org/86168 |
| *******************************************************************************/ |
| package org.eclipse.jdt.ui.wizards; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.io.UnsupportedEncodingException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.net.URI; |
| |
| import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Status; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.util.BidiUtils; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| |
| import org.eclipse.ui.PlatformUI; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.JavaConventions; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| |
| import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; |
| import org.eclipse.jdt.internal.corext.javadoc.JavaDocCommentReader; |
| import org.eclipse.jdt.internal.corext.util.InfoFilesUtil; |
| import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil; |
| import org.eclipse.jdt.internal.corext.util.JavaModelUtil; |
| import org.eclipse.jdt.internal.corext.util.Messages; |
| |
| import org.eclipse.jdt.ui.JavaUI; |
| |
| 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.TextFieldNavigationHandler; |
| import org.eclipse.jdt.internal.ui.javaeditor.DocumentAdapter; |
| import org.eclipse.jdt.internal.ui.text.javadoc.JavaDoc2HTMLTextReader; |
| import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField; |
| import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField; |
| |
| /** |
| * Wizard page to create a new package. |
| * |
| * <p> |
| * Note: This class is not intended to be subclassed, but clients can instantiate. |
| * To implement a different kind of a new package wizard page, extend <code>NewContainerWizardPage</code>. |
| * </p> |
| * |
| * @since 2.0 |
| * |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class NewPackageWizardPage extends NewContainerWizardPage { |
| |
| private static final String PACKAGE_INFO_JAVA_FILENAME= JavaModelUtil.PACKAGE_INFO_JAVA; |
| |
| private static final String PACKAGE_HTML_FILENAME= JavaModelUtil.PACKAGE_HTML; |
| |
| private static final String PAGE_NAME= "NewPackageWizardPage"; //$NON-NLS-1$ |
| |
| private static final String PACKAGE= "NewPackageWizardPage.package"; //$NON-NLS-1$ |
| |
| private final static String SETTINGS_CREATEPACKAGE_INFO_JAVA= "create_package_info_java"; //$NON-NLS-1$ |
| |
| private StringDialogField fPackageDialogField; |
| |
| private SelectionButtonDialogField fCreatePackageInfoJavaDialogField; |
| |
| /* |
| * Status of last validation of the package field |
| */ |
| private IStatus fPackageStatus; |
| |
| private IPackageFragment fCreatedPackageFragment; |
| |
| /** |
| * Creates a new <code>NewPackageWizardPage</code> |
| */ |
| public NewPackageWizardPage() { |
| super(PAGE_NAME); |
| |
| setTitle(NewWizardMessages.NewPackageWizardPage_title); |
| setDescription(NewWizardMessages.NewPackageWizardPage_description); |
| |
| fCreatedPackageFragment= null; |
| |
| PackageFieldAdapter adapter= new PackageFieldAdapter(); |
| |
| fPackageDialogField= new StringDialogField(); |
| fPackageDialogField.setDialogFieldListener(adapter); |
| fPackageDialogField.setLabelText(NewWizardMessages.NewPackageWizardPage_package_label); |
| |
| fCreatePackageInfoJavaDialogField= new SelectionButtonDialogField(SWT.CHECK); |
| fCreatePackageInfoJavaDialogField.setDialogFieldListener(adapter); |
| fCreatePackageInfoJavaDialogField.setLabelText(NewWizardMessages.NewPackageWizardPage_package_CreatePackageInfoJava); |
| |
| fPackageStatus= new StatusInfo(); |
| } |
| |
| // -------- Initialization --------- |
| |
| /** |
| * The wizard owning this page is responsible for calling this method with the |
| * current selection. The selection is used to initialize the fields of the wizard |
| * page. |
| * |
| * @param selection used to initialize the fields |
| */ |
| public void init(IStructuredSelection selection) { |
| IJavaElement jelem= getInitialJavaElement(selection); |
| |
| initContainerPage(jelem); |
| String pName= ""; //$NON-NLS-1$ |
| if (jelem != null) { |
| IPackageFragment pf= (IPackageFragment) jelem.getAncestor(IJavaElement.PACKAGE_FRAGMENT); |
| if (pf != null && !pf.isDefaultPackage()) { |
| pName= pf.getElementName(); |
| } else { |
| if (jelem.getJavaProject() != null) { |
| final IPackageFragmentRoot pkgFragmentRoot= getPackageFragmentRoot(); |
| if (pkgFragmentRoot != null && pkgFragmentRoot.exists()) { |
| try { |
| IJavaElement[] packages= pkgFragmentRoot.getChildren(); |
| if (packages.length == 1) { // only default package |
| String prName= jelem.getJavaProject().getElementName(); |
| IStatus status= getPackageStatus(prName); |
| if (status.getSeverity() == IStatus.OK) { |
| pName= prName; |
| } |
| } |
| } catch (JavaModelException e) { |
| // fall through |
| } |
| } |
| } |
| } |
| } |
| setPackageText(pName, true); |
| |
| IDialogSettings dialogSettings= getDialogSettings(); |
| if (dialogSettings != null) { |
| IDialogSettings section= dialogSettings.getSection(PAGE_NAME); |
| if (section != null) { |
| boolean createPackageDocumentation= section.getBoolean(SETTINGS_CREATEPACKAGE_INFO_JAVA); |
| fCreatePackageInfoJavaDialogField.setSelection(createPackageDocumentation); |
| } |
| } |
| |
| updateStatus(new IStatus[] { fContainerStatus, fPackageStatus }); |
| } |
| |
| // -------- UI Creation --------- |
| |
| /* |
| * @see WizardPage#createControl |
| */ |
| @Override |
| public void createControl(Composite parent) { |
| initializeDialogUnits(parent); |
| |
| Composite composite= new Composite(parent, SWT.NONE); |
| composite.setFont(parent.getFont()); |
| int nColumns= 3; |
| |
| GridLayout layout= new GridLayout(); |
| layout.numColumns= 3; |
| composite.setLayout(layout); |
| |
| Label label= new Label(composite, SWT.WRAP); |
| label.setText(NewWizardMessages.NewPackageWizardPage_info); |
| GridData gd= new GridData(); |
| gd.widthHint= convertWidthInCharsToPixels(60); |
| gd.horizontalSpan= 3; |
| label.setLayoutData(gd); |
| |
| createContainerControls(composite, nColumns); |
| createPackageControls(composite, nColumns); |
| |
| setControl(composite); |
| Dialog.applyDialogFont(composite); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.NEW_PACKAGE_WIZARD_PAGE); |
| } |
| |
| /** |
| * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean) |
| */ |
| @Override |
| public void setVisible(boolean visible) { |
| super.setVisible(visible); |
| if (visible) { |
| setFocus(); |
| } |
| } |
| |
| /** |
| * Sets the focus to the package name input field. |
| */ |
| protected void setFocus() { |
| fPackageDialogField.setFocus(); |
| } |
| |
| |
| private void createPackageControls(Composite composite, int nColumns) { |
| fPackageDialogField.doFillIntoGrid(composite, nColumns - 1); |
| Text text= fPackageDialogField.getTextControl(null); |
| LayoutUtil.setWidthHint(text, getMaxFieldWidth()); |
| LayoutUtil.setHorizontalGrabbing(text); |
| DialogField.createEmptySpace(composite); |
| |
| TextFieldNavigationHandler.install(text); |
| |
| fCreatePackageInfoJavaDialogField.doFillIntoGrid(composite, nColumns); |
| BidiUtils.applyBidiProcessing(fPackageDialogField.getTextControl(null), StructuredTextTypeHandlerFactory.JAVA); |
| } |
| |
| // -------- PackageFieldAdapter -------- |
| |
| private class PackageFieldAdapter implements IDialogFieldListener { |
| |
| // --------- IDialogFieldListener |
| |
| @Override |
| public void dialogFieldChanged(DialogField field) { |
| fPackageStatus= getPackageStatus(getPackageText()); |
| // tell all others |
| handleFieldChanged(PACKAGE); |
| } |
| } |
| |
| // -------- update message ---------------- |
| |
| /* |
| * @see org.eclipse.jdt.ui.wizards.NewContainerWizardPage#handleFieldChanged(String) |
| */ |
| @Override |
| protected void handleFieldChanged(String fieldName) { |
| super.handleFieldChanged(fieldName); |
| if (fieldName == CONTAINER) { |
| fPackageStatus= getPackageStatus(getPackageText()); |
| } |
| // do status line update |
| updateStatus(new IStatus[] { fContainerStatus, fPackageStatus }); |
| } |
| |
| // ----------- validation ---------- |
| |
| private IStatus validatePackageName(String text) { |
| IJavaProject project= getJavaProject(); |
| if (project == null || !project.exists()) { |
| return JavaConventions.validatePackageName(text, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3); |
| } |
| return JavaConventionsUtil.validatePackageName(text, project); |
| } |
| |
| /** |
| * Validates the package name and returns the status of the validation. |
| * |
| * @param packName the package name |
| * |
| * @return the status of the validation |
| */ |
| private IStatus getPackageStatus(String packName) { |
| StatusInfo status= new StatusInfo(); |
| if (packName.length() > 0) { |
| IStatus val= validatePackageName(packName); |
| if (val.getSeverity() == IStatus.ERROR) { |
| status.setError(Messages.format(NewWizardMessages.NewPackageWizardPage_error_InvalidPackageName, val.getMessage())); |
| return status; |
| } else if (val.getSeverity() == IStatus.WARNING) { |
| status.setWarning(Messages.format(NewWizardMessages.NewPackageWizardPage_warning_DiscouragedPackageName, val.getMessage())); |
| } |
| } else { |
| status.setError(NewWizardMessages.NewPackageWizardPage_error_EnterName); |
| return status; |
| } |
| |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| if (root != null && root.getJavaProject().exists()) { |
| IPackageFragment pack= root.getPackageFragment(packName); |
| try { |
| IPath rootPath= root.getPath(); |
| IPath outputPath= root.getJavaProject().getOutputLocation(); |
| if (rootPath.isPrefixOf(outputPath) && !rootPath.equals(outputPath)) { |
| // if the bin folder is inside of our root, don't allow to name a package |
| // like the bin folder |
| IPath packagePath= pack.getPath(); |
| if (outputPath.isPrefixOf(packagePath)) { |
| status.setError(NewWizardMessages.NewPackageWizardPage_error_IsOutputFolder); |
| return status; |
| } |
| } |
| if (pack.exists()) { |
| // it's ok for the package to exist as long we want to create package level documentation |
| // and the package level documentation doesn't exist |
| if (!isCreatePackageDocumentation() || packageDocumentationAlreadyExists(pack)) { |
| if (pack.containsJavaResources() || !pack.hasSubpackages()) { |
| status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageExists); |
| } else { |
| status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageNotShown); |
| } |
| } |
| } else { |
| IResource resource= pack.getResource(); |
| if (resource != null && !ResourcesPlugin.getWorkspace().validateFiltered(resource).isOK()) { |
| status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageNameFiltered); |
| return status; |
| } |
| URI location= pack.getResource().getLocationURI(); |
| if (location != null) { |
| IFileStore store= EFS.getStore(location); |
| if (store.fetchInfo().exists()) { |
| status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageExistsDifferentCase); |
| } |
| } |
| } |
| } catch (CoreException e) { |
| JavaPlugin.log(e); |
| } |
| } |
| return status; |
| } |
| |
| private boolean packageDocumentationAlreadyExists(IPackageFragment pack) throws JavaModelException { |
| ICompilationUnit packageInfoJava= pack.getCompilationUnit(PACKAGE_INFO_JAVA_FILENAME); |
| if (packageInfoJava.exists()) { |
| return true; |
| } |
| Object[] nonJavaResources= pack.getNonJavaResources(); |
| for (int i= 0; i < nonJavaResources.length; i++) { |
| Object resource= nonJavaResources[i]; |
| if (resource instanceof IFile) { |
| IFile file= (IFile) resource; |
| String fileName= file.getName(); |
| if (PACKAGE_HTML_FILENAME.equals(fileName)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns the content of the package input field. |
| * |
| * @return the content of the package input field |
| */ |
| public String getPackageText() { |
| return fPackageDialogField.getText(); |
| } |
| |
| /** |
| * Returns the content of the create package documentation input field. |
| * |
| * @return the content of the create package documentation input field |
| * @since 3.9 |
| */ |
| public boolean isCreatePackageDocumentation() { |
| return fCreatePackageInfoJavaDialogField.isSelected(); |
| } |
| |
| /** |
| * Sets the content of the package input field to the given value. |
| * |
| * @param str the new package input field text |
| * @param canBeModified if <code>true</code> the package input |
| * field can be modified; otherwise it is read-only. |
| */ |
| public void setPackageText(String str, boolean canBeModified) { |
| fPackageDialogField.setText(str); |
| |
| fPackageDialogField.setEnabled(canBeModified); |
| } |
| |
| /** |
| * Returns the resource handle that corresponds to the element that was created or |
| * will be created. |
| * @return A resource or null if the page contains illegal values. |
| * @since 3.0 |
| */ |
| public IResource getModifiedResource() { |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| if (root != null) { |
| IPackageFragment pack= root.getPackageFragment(getPackageText()); |
| IResource packRes= pack.getResource(); |
| if (isCreatePackageDocumentation()) { |
| if (JavaModelUtil.is50OrHigher(getJavaProject())) { |
| return pack.getCompilationUnit(PACKAGE_INFO_JAVA_FILENAME).getResource(); |
| } else if (packRes instanceof IFolder){ |
| return ((IFolder) packRes).getFile(PACKAGE_HTML_FILENAME); |
| } |
| } |
| |
| return packRes; |
| } |
| return null; |
| } |
| |
| |
| // ---- creation ---------------- |
| |
| /** |
| * Returns a runnable that creates a package using the current settings. |
| * |
| * @return the runnable that creates the new package |
| */ |
| public IRunnableWithProgress getRunnable() { |
| return new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| try { |
| createPackage(monitor); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| }; |
| } |
| |
| /** |
| * Returns the created package fragment. This method only returns a valid value |
| * after <code>getRunnable</code> or <code>createPackage</code> have been |
| * executed. |
| * |
| * @return the created package fragment |
| */ |
| public IPackageFragment getNewPackageFragment() { |
| return fCreatedPackageFragment; |
| } |
| |
| /** |
| * Creates the new package using the entered field values. |
| * |
| * @param monitor a progress monitor to report progress. The progress |
| * monitor must not be <code>null</code> |
| * @throws CoreException Thrown if creating the package failed. |
| * @throws InterruptedException Thrown when the operation has been canceled. |
| * @since 2.1 |
| */ |
| public void createPackage(IProgressMonitor monitor) throws CoreException, InterruptedException { |
| if (monitor == null) { |
| monitor= new NullProgressMonitor(); |
| } |
| |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| IPackageFragment pack= root.getPackageFragment(getPackageText()); |
| |
| if (pack.exists()) { |
| fCreatedPackageFragment= pack; |
| } else { |
| fCreatedPackageFragment= root.createPackageFragment(getPackageText(), true, monitor); |
| } |
| |
| if (isCreatePackageDocumentation()) { |
| if (JavaModelUtil.is50OrHigher(getJavaProject())) { |
| createPackageInfoJava(monitor); |
| } else { |
| createPackageHtml(root, monitor); |
| } |
| } |
| |
| // save whether package documentation should be created |
| IDialogSettings dialogSettings= getDialogSettings(); |
| if (dialogSettings != null) { |
| IDialogSettings section= dialogSettings.getSection(PAGE_NAME); |
| if (section == null) { |
| section= dialogSettings.addNewSection(PAGE_NAME); |
| } |
| section.put(SETTINGS_CREATEPACKAGE_INFO_JAVA, isCreatePackageDocumentation()); |
| } |
| |
| if (monitor.isCanceled()) { |
| throw new InterruptedException(); |
| } |
| } |
| |
| private void createPackageInfoJava(IProgressMonitor monitor) throws CoreException { |
| StringBuilder fileContent= new StringBuilder(); |
| fileContent.append("package "); //$NON-NLS-1$ |
| fileContent.append(fCreatedPackageFragment.getElementName()); |
| fileContent.append(";"); //$NON-NLS-1$ |
| |
| InfoFilesUtil.createInfoJavaFile(PACKAGE_INFO_JAVA_FILENAME, fileContent.toString(), fCreatedPackageFragment, monitor); |
| } |
| |
| private void createPackageHtml(IPackageFragmentRoot root, IProgressMonitor monitor) throws CoreException { |
| IWorkspace workspace= ResourcesPlugin.getWorkspace(); |
| IFolder createdPackage= workspace.getRoot().getFolder(fCreatedPackageFragment.getPath()); |
| IFile packageHtml= createdPackage.getFile(PACKAGE_HTML_FILENAME); |
| String charset= packageHtml.getCharset(); |
| String content= buildPackageHtmlContent(root, charset); |
| try { |
| packageHtml.create(new ByteArrayInputStream(content.getBytes(charset)), false, monitor); |
| } catch (UnsupportedEncodingException e) { |
| String message= "charset " + charset + " not supported by platform"; //$NON-NLS-1$ //$NON-NLS-2$ |
| throw new CoreException(new Status(IStatus.ERROR, JavaUI.ID_PLUGIN, message, e)); |
| } |
| } |
| |
| private String buildPackageHtmlContent(IPackageFragmentRoot root, String charset) throws CoreException { |
| String lineDelimiter= StubUtility.getLineDelimiterUsed(root.getJavaProject()); |
| StringBuilder content = new StringBuilder(); |
| String fileComment= InfoFilesUtil.getFileComment(PACKAGE_INFO_JAVA_FILENAME, fCreatedPackageFragment, lineDelimiter); |
| String typeComment= InfoFilesUtil.getTypeComment(PACKAGE_INFO_JAVA_FILENAME, fCreatedPackageFragment, lineDelimiter); |
| |
| content.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| if (fileComment != null) { |
| content.append("<!--"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append(stripJavaComments(fileComment)); |
| content.append(lineDelimiter); |
| content.append("-->"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| } |
| content.append("<html>"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append("<head>"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset="); //$NON-NLS-1$ |
| content.append(charset); |
| content.append("\">"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append("<title>"); //$NON-NLS-1$ |
| content.append(fCreatedPackageFragment.getElementName()); |
| content.append("</title>"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append("</head>"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append("<body>"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| |
| if (typeComment != null) { |
| content.append(stripJavaComments(typeComment)); |
| content.append(lineDelimiter); |
| } |
| |
| content.append("</body>"); //$NON-NLS-1$ |
| content.append(lineDelimiter); |
| content.append("</html>"); //$NON-NLS-1$ |
| |
| return content.toString(); |
| } |
| |
| private String stripJavaComments(String comment) { |
| DocumentAdapter documentAdapter= new DocumentAdapter(null, fCreatedPackageFragment.getPath()); |
| try { |
| documentAdapter.setContents(comment); |
| return getString(new JavaDoc2HTMLTextReader(new JavaDocCommentReader(documentAdapter, 0, comment.length()))); |
| } finally { |
| documentAdapter.close(); |
| } |
| } |
| |
| private static String getString(Reader reader) { |
| StringBuffer buf= new StringBuffer(); |
| char[] buffer= new char[1024]; |
| int count; |
| try { |
| while ((count= reader.read(buffer)) != -1) |
| buf.append(buffer, 0, count); |
| } catch (IOException e) { |
| return null; |
| } |
| return buf.toString(); |
| } |
| |
| } |