com.google.dart.tools.debug.core.util.ResourceServer.java Source code

Java tutorial

Introduction

Here is the source code for com.google.dart.tools.debug.core.util.ResourceServer.java

Source

/*
 * Copyright (c) 2012, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.dart.tools.debug.core.util;

import com.google.common.io.CharStreams;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.model.DartLibrary;
import com.google.dart.tools.core.model.DartModelException;
import com.google.dart.tools.core.model.DartProject;
import com.google.dart.tools.core.model.HTMLFile;
import com.google.dart.tools.debug.core.DartDebugCorePlugin;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * A web server that serves up workspace resources.
 */
public class ResourceServer implements IResourceResolver {
    private ServerSocket serverSocket;
    private ExecutorService threadPool;

    private Set<String> previousAgents = new HashSet<String>();

    /**
     * Create a ResourceServer; serve its resources from any free port.
     * 
     * @throws IOException
     */
    public ResourceServer() throws IOException {
        this(0);
    }

    /**
     * Create a ResourceServer; serve its resources from the given port.
     * 
     * @throws IOException
     */
    public ResourceServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        threadPool = Executors.newCachedThreadPool();

        new Thread(new Runnable() {
            @Override
            public void run() {
                startServer();
            }
        }, "Web Server Dispatch").start();
    }

    /**
     * @return the user's IP address, if available (null otherwise)
     */
    public String getLocalAddress() {
        return NetUtils.getIpAddress();
    }

    public int getPort() {
        return serverSocket.getLocalPort();
    }

    @Override
    public String getUrlForFile(File file) {
        return getUrlForUri(file.toURI());
    }

    @Override
    public String getUrlForResource(IResource resource) {
        URI fileUri = resource.getLocation().toFile().toURI();

        return getUrlForUri(fileUri);
    }

    /**
     * Close the resource server.
     */
    public void shutdown() {
        try {
            serverSocket.close();
        } catch (IOException exception) {
            DartDebugCorePlugin.logError(exception);
        }
    }

    protected String getAvailableAppsContent() throws IOException {
        InputStream in = ResourceServer.class.getResourceAsStream("template.html");

        String template = CharStreams.toString(new InputStreamReader(in));

        List<HTMLFile> appFiles = getAllHtmlFiles();

        // Sort by project name, then html file name
        Collections.sort(appFiles, new Comparator<HTMLFile>() {
            @Override
            public int compare(HTMLFile o1, HTMLFile o2) {
                String str1 = o1.getDartProject().getElementName() + " " + o1.getElementName();
                String str2 = o2.getDartProject().getElementName() + " " + o2.getElementName();

                return str1.compareToIgnoreCase(str2);
            }
        });

        if (appFiles.size() == 0) {
            template = replaceTemplate(template, "count", "No");
            template = replaceTemplate(template, "apps", "");
        } else {
            template = replaceTemplate(template, "count", Integer.toString(appFiles.size()));

            StringBuilder builder = new StringBuilder();

            for (HTMLFile htmlFile : appFiles) {
                try {
                    if (htmlFile.getReferencedLibraries().length < 1) {
                        continue;
                    }

                    IResource htmlResource = htmlFile.getCorrespondingResource();
                    DartLibrary library = htmlFile.getReferencedLibraries()[0];
                    IResource libraryResource = library.getCorrespondingResource();

                    String href = "<a href=\"" + getPathFor(htmlFile) + "\">";

                    builder.append("<div class=\"app\"><table><tr>");
                    builder.append(
                            "<td rowspan=2>" + href + "<img src=\"dart_32_32.gif\" width=32 height=32></a></td>");
                    builder.append("<td class=\"title\">" + htmlResource.getProject().getName() + " - " + href
                            + htmlFile.getElementName() + "</a></td</tr>");
                    builder.append("<tr><td class=\"info\">" + webSafe(libraryResource.getFullPath().toOSString())
                            + "</td></tr>");
                    builder.append("</table></div>");
                } catch (DartModelException dme) {

                }
            }

            template = replaceTemplate(template, "apps", builder.toString());
        }

        return template;
    }

    protected void loadingContentFrom(String hostAddress, String userAgent) {
        if (!previousAgents.contains(userAgent)) {
            previousAgents.add(userAgent);

            DartCore.getConsole().println("Remote connection from " + hostAddress + " [" + userAgent + "]");
        }
    }

    private List<HTMLFile> getAllHtmlFiles() {
        Set<HTMLFile> files = new HashSet<HTMLFile>();

        for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
            DartProject dartProject = DartCore.create(project);

            if (dartProject != null) {
                try {
                    for (DartLibrary library : dartProject.getDartLibraries()) {
                        List<HTMLFile> htmlFiles = library.getChildrenOfType(HTMLFile.class);

                        files.addAll(htmlFiles);
                    }
                } catch (DartModelException ex) {

                }
            }
        }

        return new ArrayList<HTMLFile>(files);
    }

    private String getPathFor(HTMLFile htmlFile) throws IOException {
        try {
            String url = getUrlForResource(htmlFile.getCorrespondingResource());

            return URI.create(url).getPath();
        } catch (DartModelException ex) {
            throw new IOException(ex);
        }
    }

    private String getUrlForUri(URI fileUri) {
        try {
            String pathSegment = fileUri.getPath();

            // localhost? 127.0.0.1? serverSocket.getInetAddress().getHostAddress()?
            URI uri = new URI("http", null, "127.0.0.1", serverSocket.getLocalPort(), pathSegment, null, null);
            return uri.toString();
        } catch (URISyntaxException e) {
            DartDebugCorePlugin.logError(e);

            return null;
        }
    }

    private String replaceTemplate(String template, String target, String replace) {
        target = "${" + target + "}";

        int index = template.indexOf(target);

        String template1 = template.substring(0, index);
        String template2 = template.substring(index + target.length());

        return template1 + replace + template2;
    }

    private void startServer() {
        try {
            while (true) {
                Socket socket = serverSocket.accept();

                threadPool.execute(new ResourceServerHandler(this, socket));
            }
        } catch (IOException e) {
            // The server socket was closed by the shutdown() call.

        }
    }

    private String webSafe(String s) {
        StringBuffer out = new StringBuffer();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c > 127 || c == '"' || c == '<' || c == '>') {
                out.append("&#" + (int) c + ";");
            } else {
                out.append(c);
            }
        }

        return out.toString();
    }

}