Package com.google.gdt.eclipse.designer.util

Source Code of com.google.gdt.eclipse.designer.util.ModuleVisitor

/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* 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
*
* 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.gdt.eclipse.designer.util;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.gdt.eclipse.designer.IExceptionConstants;
import com.google.gdt.eclipse.designer.model.module.InheritsElement;
import com.google.gdt.eclipse.designer.model.module.ModuleElement;
import com.google.gdt.eclipse.designer.model.module.PublicElement;
import com.google.gdt.eclipse.designer.model.module.SourceElement;
import com.google.gdt.eclipse.designer.model.module.SuperSourceElement;
import com.google.gdt.eclipse.designer.util.resources.IResourcesProvider;

import org.eclipse.wb.internal.core.utils.check.Assert;
import org.eclipse.wb.internal.core.utils.jdt.core.CodeUtils;

import java.io.InputStream;
import java.util.List;
import java.util.Set;

/**
* A visitor for GWT modules structure.
*
* @author scheglov_ke
* @coverage gwt.util
*/
public abstract class ModuleVisitor {
  ////////////////////////////////////////////////////////////////////////////
  //
  // ClassLoader
  //
  ////////////////////////////////////////////////////////////////////////////
  private IResourcesProvider m_resourcesProvider;

  /**
   * @return the {@link IResourcesProvider} that is used for visiting modules.
   */
  public final IResourcesProvider getResourcesProvider() {
    return m_resourcesProvider;
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Visitor interface
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Enters into module.
   *
   * @return <code>true</code> if this module should be visited.
   */
  public boolean visitModule(ModuleElement module) {
    return true;
  }

  /**
   * Leaves module.
   */
  public void endVisitModule(ModuleElement module) {
  }

  /**
   * Visits "source" package of module.
   *
   * @param module
   *          the module to which belongs "source" package.
   * @param packageName
   *          the qualified name of "source" package.
   * @param superSource
   *          is <code>true</code> if this source package comes from <code>super-source</code> tag
   *          and <code>false</code> if from usual <code>source</code> tag.
   */
  public void visitSourcePackage(ModuleElement module, String packageName, boolean superSource)
      throws Exception {
  }

  /**
   * Visits "public" package of module.
   *
   * @param module
   *          the module to which belongs "public" package.
   * @param packageName
   *          the qualified name of "public" package.
   */
  public void visitPublicPackage(ModuleElement module, String packageName) throws Exception {
  }

  ////////////////////////////////////////////////////////////////////////////
  //
  // Visiting implementation
  //
  ////////////////////////////////////////////////////////////////////////////
  /**
   * Visits public folders of given module and inherited modules (recursively).
   */
  public static void accept(ModuleDescription moduleDescription, ModuleVisitor visitor)
      throws Exception {
    IResourcesProvider resourcesProvider = moduleDescription.getResourcesProvider();
    visitor.m_resourcesProvider = resourcesProvider;
    {
      String moduleId = moduleDescription.getId();
      accept(resourcesProvider, Sets.<String>newTreeSet(), moduleId, visitor);
    }
  }

  /**
   * Visit modules recursively.
   */
  private static void accept(IResourcesProvider resources,
      Set<String> visitedModules,
      String moduleName,
      ModuleVisitor visitor) throws Exception {
    // check that module is not from gwt-dev-xxx.jar
    if (moduleName.startsWith("com.google.gwt.dev")) {
      return;
    }
    // check, may be we already visited this module
    if (visitedModules.contains(moduleName)) {
      return;
    }
    visitedModules.add(moduleName);
    // prepare module
    ModuleElement module;
    {
      String moduleResourceName = moduleName.replace('.', '/') + ".gwt.xml";
      // prepare stream
      InputStream is = resources.getResourceAsStream(moduleResourceName);
      Assert.isTrueException(is != null, IExceptionConstants.NO_MODULE, moduleName);
      // read module
      module = Utils.readModule(moduleName, is);
    }
    // start visit module
    if (!visitor.visitModule(module)) {
      return;
    }
    String modulePackageName = CodeUtils.getPackage(moduleName);
    // visit "source" packages
    {
      List<SuperSourceElement> superSourceElements = module.getSuperSourceElements();
      List<SourceElement> sourceElements = module.getSourceElements();
      // visit explicit
      for (SuperSourceElement sourceElement : superSourceElements) {
        visitSourcePackage(visitor, module, modulePackageName, sourceElement.getPath(), true);
      }
      for (SourceElement sourceElement : sourceElements) {
        visitSourcePackage(visitor, module, modulePackageName, sourceElement.getPath(), false);
      }
      // no any source elements, use default
      if (superSourceElements.isEmpty() && sourceElements.isEmpty()) {
        visitSourcePackage(visitor, module, modulePackageName, "client", false);
      }
    }
    // visit "public" folders
    {
      // prepare folders
      List<PublicElement> publicElements = module.getPublicElements();
      if (publicElements.isEmpty()) {
        PublicElement defaultPublicElement = new PublicElement();
        defaultPublicElement.setPath("public");
        publicElements = ImmutableList.of(defaultPublicElement);
      }
      // visit folders
      for (PublicElement publicElement : publicElements) {
        String packageName = modulePackageName + "." + publicElement.getPath().replace('/', '.');
        visitor.visitPublicPackage(module, packageName);
      }
    }
    // try inherited modules
    {
      List<InheritsElement> inheritsElements = module.getInheritsElements();
      for (InheritsElement inheritsElement : inheritsElements) {
        String inheritsName = inheritsElement.getName();
        Assert.isTrueException(
            inheritsName != null,
            IExceptionConstants.INHERITS_NO_NAME,
            moduleName);
        accept(resources, visitedModules, inheritsName, visitor);
      }
    }
    // end visit modules
    visitor.endVisitModule(module);
  }

  /**
   * Visits single "source" package.
   *
   * @param visitor
   *          the {@link ModuleVisitor} to visit.
   * @param module
   *          the module that has this "source" package.
   * @param modulePackageName
   *          the name of package in which module is located.
   * @param pathInModule
   *          the simple path to the "source" folder, as it is described in module file, may be
   *          <code>null</code> if <code>modulePackage</code> itself should be used as source folder
   *          (probably only for <code>super-source</code>).
   * @param superSource
   *          is <code>true</code> if this source package comes from <code>super-source</code> tag
   *          and <code>false</code> if from usual <code>source</code> tag.
   */
  private static void visitSourcePackage(ModuleVisitor visitor,
      ModuleElement module,
      String modulePackageName,
      String pathInModule,
      boolean superSource) throws Exception {
    if (pathInModule == null) {
      visitor.visitSourcePackage(module, modulePackageName, superSource);
    } else {
      visitor.visitSourcePackage(
          module,
          modulePackageName + "." + pathInModule.replace('/', '.'),
          superSource);
    }
  }
}
TOP

Related Classes of com.google.gdt.eclipse.designer.util.ModuleVisitor

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.