Package org.apache.wicket.examples.source

Source Code of org.apache.wicket.examples.source.SourcesPage$CodePanel

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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 org.apache.wicket.examples.source;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.JarURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.Component;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.PopupCloseLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.io.IOUtils;
import org.apache.wicket.util.lang.PackageName;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.apache.wicket.util.string.Strings;

import com.uwyn.jhighlight.renderer.Renderer;
import com.uwyn.jhighlight.renderer.XhtmlRendererFactory;


/**
* Displays the resources in a packages directory in a browsable format.
*
* @author Martijn Dashorst
*/
public class SourcesPage extends WebPage
{
  private static final Log log = LogFactory.getLog(SourcesPage.class);

  /**
   * Model for retrieving the source code from the classpath of a packaged
   * resource.
   */
  public class SourceModel extends AbstractReadOnlyModel
  {
    /**
     * Constructor.
     */
    public SourceModel()
    {
    }

    /**
     * Returns the contents of the file loaded from the classpath.
     *
     * @return the contents of the file identified by name
     */
    public Object getObject()
    {
      // name contains the name of the selected file
      if (Strings.isEmpty(name))
      {
        return "";
      }
      BufferedReader br = null;
      try
      {
        StringBuffer sb = new StringBuffer();

        InputStream resourceAsStream = page.getResourceAsStream(name);
        if (resourceAsStream == null)
        {
          return "Unable to read the source for " + name;
        }
        br = new BufferedReader(new InputStreamReader(resourceAsStream));

        while (br.ready())
        {
          sb.append(br.readLine());
          sb.append("\n");
        }
        int lastDot = name.lastIndexOf('.');
        if (lastDot != -1)
        {
          String type = name.substring(lastDot + 1);
          Renderer renderer = XhtmlRendererFactory.getRenderer(type);
          if (renderer != null)
          {
            return renderer.highlight(name, sb.toString(), "UTF-8", true);
          }
        }
        return Strings.escapeMarkup(sb.toString(), false, true).toString().replaceAll("\n", "<br />");
      }
      catch (IOException e)
      {
        log.error("Unable to read resource stream for: " + name + "; Page="
            + page.toString(), e);
        return "";
      }
      finally
      {
        IOUtils.closeQuietly(br);
      }
    }   
  }

  /**
   * Model for retrieving the contents of a package directory from the class
   * path.
   */
  public class PackagedResourcesModel extends AbstractReadOnlyModel implements IDetachable
  {
    private final List resources = new ArrayList();

    /**
     * Constructor.
     */
    public PackagedResourcesModel()
    {
    }

    /**
     * Clears the list to save space.
     */
    protected void onDetach()
    {
      resources.clear();
    }

    /**
     * Returns the list of resources found in the package of the page.
     *
     * @return the list of resources found in the package of the page.
     */
    public Object getObject()
    {
      if (resources.isEmpty())
      {
        get(page);
//        PackageName name = PackageName.forClass(page);
//        ClassLoader loader = page.getClassLoader();
//        String path = Strings.replaceAll(name.getName(), ".", "/").toString();
//        try
//        {
//          // gives the urls for each place where the package
//          // path could be found. There could be multiple
//          // jar files containing the same package, so each
//          // jar file has its own url.
//
//          Enumeration urls = loader.getResources(path);
//          while (urls.hasMoreElements())
//          {
//            URL url = (URL)urls.nextElement();
//
//            // the url points to the directory structure
//            // embedded in the classpath.
//
//            getPackageContents(url);
//          }
//        }
//        catch (IOException e)
//        {
//          log.error("Unable to read resource for: " + path, e);
//        }
      }
      return resources;
    }

    /**
     * Retrieves the package contents for the given URL.
     *
     * @param packageListing
     *            the url to list.
     */
    private void getPackageContents(URL packageListing)
    {
      BufferedReader br = null;
      try
      {
        InputStream openStream = packageListing.openStream();
        if (openStream == null)
        {
          return;
        }
        br = new BufferedReader(new InputStreamReader(openStream));

        while (br.ready())
        {
          String listing = br.readLine();
          String extension = Strings.afterLast(listing, '.');
          if (!listing.endsWith("class"))
          {
            resources.add(listing);
          }
        }
      }
      catch (IOException e)
      {
        log.error("Unable to get package content: " + packageListing.toString(), e);
      }
      finally
      {
        IOUtils.closeQuietly(br);
      }
    }

    private final void addResources(final Class scope, final AppendingStringBuffer relativePath, final File dir)
    {
      File[] files = dir.listFiles();
      for (int i = 0; i < files.length; i++)
      {
        File file = files[i];
        if (file.isDirectory())
        {
          addResources(scope,  new AppendingStringBuffer(relativePath).append(file.getName()).append('/'), file);
        }
        else
        {
          String name = file.getName();
          String extension = Strings.afterLast(name, '.');
          if (!name.endsWith("class"))
          {
            resources.add(relativePath + name);
          }
         
        }
      }
    }

    private void get(Class scope)
    {
      String packageRef = Strings.replaceAll(PackageName.forClass(scope).getName(), ".", "/").toString();
      ClassLoader loader = scope.getClassLoader();
      try
      {
        // loop through the resources of the package
        Enumeration packageResources = loader.getResources(packageRef);
        while (packageResources.hasMoreElements())
        {
          URL resource = (URL)packageResources.nextElement();
          URLConnection connection = resource.openConnection();
          if (connection instanceof JarURLConnection)
          {
            JarFile jf = ((JarURLConnection)connection).getJarFile();
            scanJarFile(scope, packageRef, jf);
          }
          else
          {
            String absolutePath = scope.getResource("").toExternalForm();
            File basedir;
            URI uri;
            try
            {
              uri = new URI(absolutePath);
            }
            catch (URISyntaxException e)
            {
              throw new RuntimeException(e);
            }
            try
            {
              basedir = new File(uri);
            }
            catch(IllegalArgumentException e)
            {
              log.debug("Can't construct the uri as a file: " + absolutePath);
              // if this is throwen then the path is not really a file. but could be a zip.
              String jarZipPart = uri.getSchemeSpecificPart();
              // lowercased for testing if jar/zip, but leave the real filespec unchanged
              String lowerJarZipPart = jarZipPart.toLowerCase();
              int index = lowerJarZipPart.indexOf(".zip");
              if(index == -1) index = lowerJarZipPart.indexOf(".jar");
              if(index == -1) throw e;
             
              String filename = jarZipPart.substring(0, index+4); // 4 = len of ".jar" or ".zip"
              log.debug("trying the filename: " + filename + " to load as a zip/jar.");
              JarFile jarFile = new JarFile(filename,false);
              scanJarFile(scope, packageRef, jarFile);
              return;
            }
            if (!basedir.isDirectory())
            {
              throw new IllegalStateException("unable to read resources from directory "
                  + basedir);
            }
            addResources(scope, new AppendingStringBuffer(), basedir);
          }
        }
      }
      catch (IOException e)
      {
        throw new WicketRuntimeException(e);
      }
      Collections.sort(resources);
      return;
    }

    private void scanJarFile(Class scope,String packageRef, JarFile jf)
    {
      Enumeration enumeration = jf.entries();
      while (enumeration.hasMoreElements())
      {
        JarEntry je = (JarEntry)enumeration.nextElement();
        String name = je.getName();
        if (name.startsWith(packageRef))
        {
          name = name.substring(packageRef.length() + 1);
          String extension = Strings.afterLast(name, '.');
          if (!name.endsWith("class"))
          {
            resources.add(name);
          }
        }
      }
    }
  }

  /**
   * Displays the resources embedded in a package in a list.
   */
  public class FilesBrowser extends WebMarkupContainer
  {
    /**
     * Constructor.
     *
     * @param id
     *            the component identifier
     */
    public FilesBrowser(String id)
    {
      super(id);
      ListView lv = new ListView("file", new PackagedResourcesModel())
      {
        protected void populateItem(ListItem item)
        {
          AjaxFallbackLink link = new AjaxFallbackLink("link", item.getModel())
          {
            public void onClick(AjaxRequestTarget target)
            {
              setName(getModelObjectAsString());

              if (target != null)
              {
                target.addComponent(codePanel);
                target.addComponent(filename);
              }
            }
          };
          link.add(new Label("name", item.getModelObjectAsString()));
          item.add(link);
        }
      };
      add(lv);
    }
  }

  /**
   * Container for displaying the source of the selected page, resource or
   * other element from the package.
   */
  public class CodePanel extends WebMarkupContainer
  {
    /**
     * Constructor.
     *
     * @param id
     *            the component id
     */
    public CodePanel(String id)
    {
      super(id);
      Label code = new Label("code", new SourceModel());
      code.setEscapeModelStrings(false);
      code.setOutputMarkupId(true);
      add(code);
    }
  }

  /**
   * The selected name of the packaged resource to display.
   */
  private String name;

  /**
   * The class of the page of which the sources need to be displayed.
   */
  private Class page;

  /**
   * The panel for setting the ajax calls.
   */
  private Component codePanel;

  private Label filename;

  /**
   * Sets the name.
   *
   * @param name
   *            the name to set.
   */
  public void setName(String name)
  {
    this.name = name;
  }

  /**
   * Gets the name.
   *
   * @return the name.
   */
  public String getName()
  {
    return name;
  }

  /**
   * Default constructor, only used for test purposes.
   */
  public SourcesPage()
  {
    this(SourcesPage.class);
  }

  /**
   * Constructor.
   *
   * @param page
   *            the page where the sources need to be shown from.
   */
  public SourcesPage(Class page)
  {
    this.page = page;

    filename = new Label("filename", new PropertyModel(this, "name"));
    filename.setOutputMarkupId(true);
    add(filename);
    codePanel = new CodePanel("codepanel").setOutputMarkupId(true);
    add(codePanel);
    add(new FilesBrowser("filespanel"));
    add(new PopupCloseLink("close"));
  }
}
TOP

Related Classes of org.apache.wicket.examples.source.SourcesPage$CodePanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.