org.eclipse.php.internal.ui.util.PHPManual.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.php.internal.ui.util.PHPManual.java

Source

/*******************************************************************************
 * Copyright (c) 2009 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
 *     Zend Technologies
 *******************************************************************************/
package org.eclipse.php.internal.ui.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.dltk.ast.declarations.Declaration;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.core.*;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.php.internal.core.compiler.ast.nodes.IPHPDocAwareDeclaration;
import org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocBlock;
import org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocTag;
import org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocTagKinds;
import org.eclipse.php.internal.core.typeinference.PHPModelUtils;
import org.eclipse.php.internal.ui.Logger;
import org.eclipse.php.internal.ui.PHPUIMessages;
import org.eclipse.php.internal.ui.PHPUiPlugin;
import org.eclipse.php.internal.ui.preferences.PreferenceConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;

public class PHPManual {

    private static final String BROWSER_ID = "PHPManual.browser"; //$NON-NLS-1$
    private static final Pattern HTTP_URL_PATTERN = Pattern.compile("http://[^\\s]*"); //$NON-NLS-1$
    private static int browserCount = 0;

    private PHPManualSite site;
    private static Map<String, String> phpEntityPathMap;

    public PHPManual(PHPManualSite site) {
        this.site = site;
    }

    public PHPManualSite getSite() {
        return site;
    }

    public void setSite(PHPManualSite site) {
        this.site = site;
    }

    private synchronized Map<String, String> getPHPEntityPathMap() {
        if (phpEntityPathMap == null) {
            phpEntityPathMap = new HashMap<String, String>();
            URL url = FileLocator.find(Platform.getBundle(PHPUiPlugin.getPluginId()), new Path("phpdoc.mapping"), //$NON-NLS-1$
                    null);
            if (url != null) {
                try {
                    BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream()));
                    String line;
                    while ((line = r.readLine()) != null) {
                        int sepIdx = line.indexOf('=');
                        if (sepIdx != -1) {
                            phpEntityPathMap.put(line.substring(0, sepIdx).toLowerCase(),
                                    line.substring(sepIdx + 1));
                        }
                    }
                } catch (IOException e) {
                }
            }
        }
        return phpEntityPathMap;
    }

    /**
     * XXX: support manual for keywords This method tries to determine PHP
     * manual URL for the specified PHP element
     * 
     * @param codeData
     *            PHP element code data
     * @return URL for the manual page
     */
    public String getURLForManual(IModelElement modelElement) {
        if (modelElement == null) {
            throw new IllegalArgumentException();
        }

        String path = null;
        if (modelElement instanceof IMethod) {
            try {
                IModelElement ancestor = ((IMethod) modelElement).getAncestor(IModelElement.TYPE);
                if (null != ancestor) {
                    // if this is actually a method (not function), checking for
                    // declaring class manual
                    path = buildPathForClass((IType) ancestor);
                } else {
                    path = buildPathForMethod((IMethod) modelElement);
                }
            } catch (ModelException e) {
                Logger.logException(e);
            }
        } else if (modelElement instanceof IType) {
            try {
                path = buildPathForClass((IType) modelElement);
            } catch (ModelException e) {
                Logger.logException(e);
            }
        }
        if (path != null) {
            StringBuffer url = new StringBuffer();
            url.append(site.getUrl());
            if (!site.getUrl().endsWith("/")) { //$NON-NLS-1$
                url.append("/"); //$NON-NLS-1$
            }
            url.append(path);
            url.append("."); //$NON-NLS-1$
            url.append(site.getExtension());

            return url.toString();
        }
        return null;
    }

    private String getPHPDocLink(Declaration declaration) {
        String path = null;
        if (declaration instanceof IPHPDocAwareDeclaration) {
            IPHPDocAwareDeclaration phpDocDeclaration = (IPHPDocAwareDeclaration) declaration;

            PHPDocBlock docBlock = phpDocDeclaration.getPHPDoc();
            if (docBlock != null) {
                for (PHPDocTag docTag : docBlock.getTags(PHPDocTagKinds.LINK)) {
                    Matcher m = HTTP_URL_PATTERN.matcher(docTag.getValue().trim());
                    if (m.find()) {
                        try {
                            URL url = new URL(m.group());
                            path = new File(url.getFile()).getName();
                            int extIdx = path.lastIndexOf('.');
                            if (extIdx > 0) {
                                path = path.substring(0, extIdx);
                            }
                            break;
                        } catch (MalformedURLException e) {
                        }
                    }
                }
            }
        }
        return path;
    }

    protected String buildPathForClass(IType type) throws ModelException {
        String path = null;
        if (type != null) {
            ISourceModule sourceModule = type.getSourceModule();
            ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(sourceModule);
            TypeDeclaration typeDeclaration = PHPModelUtils.getNodeByClass(moduleDeclaration, type);
            path = getPHPDocLink(typeDeclaration);

            if (path == null) {

                String className = type.getElementName();
                path = (String) getPHPEntityPathMap().get(className.toLowerCase());
                if (path == null) {
                    path = buildPathForClass(type.getElementName());
                }
            }
        }
        return path;
    }

    private String buildPathForClass(String className) {
        StringBuffer buf = new StringBuffer();
        buf.append("class."); //$NON-NLS-1$
        if (className != null) {
            buf.append(className);
        }
        return buf.toString().toLowerCase();
    }

    protected String buildPathForMethod(IMethod method) {

        ISourceModule sourceModule = method.getSourceModule();
        ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(sourceModule);
        MethodDeclaration methodDeclaration;
        try {
            methodDeclaration = PHPModelUtils.getNodeByMethod(moduleDeclaration, method);
        } catch (ModelException e) {
            return null;
        }

        String path = getPHPDocLink(methodDeclaration);
        if (path == null) {
            IType declaringType = method.getDeclaringType();
            if (declaringType != null) {
                String functionName = declaringType.getElementName() + "::" //$NON-NLS-1$
                        + method.getElementName();
                path = (String) getPHPEntityPathMap().get(functionName.toLowerCase());
                if (path == null) {
                    path = buildPathForMethod(declaringType.getElementName(), method.getElementName());
                }
            } else {
                path = (String) getPHPEntityPathMap().get(method.getElementName().toLowerCase());
                if (path == null) {
                    path = buildPathForMethod(null, method.getElementName());
                }
            }
        }
        return path;
    }

    protected String buildPathForMethod(String className, String methodName) {
        StringBuffer buf = new StringBuffer();
        buf.append("function."); //$NON-NLS-1$
        if (className != null) {
            buf.append(className);
            buf.append("-"); //$NON-NLS-1$
        }
        buf.append(Pattern.compile("([A-Z])").matcher(methodName) //$NON-NLS-1$
                .replaceAll("-$1").replaceAll("_", "-")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        return buf.toString().toLowerCase().replaceAll("-+", "-"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    /**
     * This function launches browser and shows PHP manual page for the
     * specified URL
     */
    public void showFunctionHelp(String url) {
        IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench().getBrowserSupport();
        IWebBrowser browser;
        try {
            IPreferenceStore store = PHPUiPlugin.getDefault().getPreferenceStore();
            if (store.getBoolean(PreferenceConstants.PHP_MANUAL_OPEN_IN_NEW_BROWSER)) {
                browser = browserSupport.createBrowser(BROWSER_ID + ++browserCount);
            } else {
                browser = browserSupport.createBrowser(BROWSER_ID);
            }

            if (url.startsWith("mk:")) { //$NON-NLS-1$
                browser.openURL(new URL(null, url, new MkHandler()));
            } else if (url.startsWith("help://")) { //$NON-NLS-1$
                // convert to help system URL
                String helpURL = url.substring("help://".length()); //$NON-NLS-1$
                // open in Help System
                PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpURL);

            } else {
                URL url2 = validateUrlExists(url);
                if (null == url2) {

                    // need to open some kind of err dialog and return
                    MessageDialog d = new MessageDialog(
                            PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                            PHPUIMessages.PHPManual_title, null, PHPUIMessages.PHPManual_noManual_msg,
                            MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0);
                    d.open();
                    return;
                }
                browser.openURL(url2);
            }

        } catch (PartInitException e) {
            Logger.logException(e);
        } catch (MalformedURLException e) {
            Logger.logException(e);
        }
    }

    protected URL validateUrlExists(String url) throws MalformedURLException {
        URL url2 = new URL(url);
        if ("file".equals(url2.getProtocol())) { //$NON-NLS-1$
            return validateFileUrlExists(url, url2);
        }
        // else if ("http".equals(url2.getProtocol())){
        // return validateHttpUrlExists(url, url2);
        // }
        return url2;
    }

    private URL validateFileUrlExists(String url, URL url2) {
        File file = new File(url.substring("file://".length())); //$NON-NLS-1$
        if (null != file && file.exists()) {
            return url2;
        } else {
            return null;
        }
    }

    private class MkHandler extends URLStreamHandler {
        protected URLConnection openConnection(URL arg0) throws IOException {
            return null;
        }
    }
}