Package org.objectstyle.wolips.wodclipse.core.builder

Source Code of org.objectstyle.wolips.wodclipse.core.builder.WodBuilder$ValidatingComponent

/*
* ====================================================================
*
* The ObjectStyle Group Software License, Version 1.0
*
* Copyright (c) 2005 - 2006 The ObjectStyle Group and individual authors of the
* software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: 1.
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. The end-user documentation
* included with the redistribution, if any, must include the following
* acknowlegement: "This product includes software developed by the ObjectStyle
* Group (http://objectstyle.org/)." Alternately, this acknowlegement may
* appear in the software itself, if and wherever such third-party
* acknowlegements normally appear. 4. The names "ObjectStyle Group" and
* "Cayenne" must not be used to endorse or promote products derived from this
* software without prior written permission. For written permission, please
* contact andrus@objectstyle.org. 5. Products derived from this software may
* not be called "ObjectStyle" nor may "ObjectStyle" appear in their names
* without prior written permission of the ObjectStyle Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* OBJECTSTYLE GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many individuals
* on behalf of the ObjectStyle Group. For more information on the ObjectStyle
* Group, please see <http://objectstyle.org/> .
*/
package org.objectstyle.wolips.wodclipse.core.builder;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.preference.IPreferenceStore;
import org.objectstyle.wolips.bindings.Activator;
import org.objectstyle.wolips.bindings.preferences.PreferenceConstants;
import org.objectstyle.wolips.core.resources.builder.AbstractFullAndIncrementalBuilder;
import org.objectstyle.wolips.core.resources.types.SuperTypeHierarchyCache;
import org.objectstyle.wolips.core.resources.types.WOHierarchyScope;
import org.objectstyle.wolips.locate.LocatePlugin;
import org.objectstyle.wolips.locate.result.LocalizedComponentsLocateResult;
import org.objectstyle.wolips.variables.BuildProperties;
import org.objectstyle.wolips.variables.VariablesPlugin;
import org.objectstyle.wolips.wodclipse.core.completion.WodParserCache;
import org.objectstyle.wolips.wodclipse.core.util.WodModelUtils;

public class WodBuilder extends AbstractFullAndIncrementalBuilder {
  private static ExecutorService validationThreadPool;
  private static ValidationProgressJob _validationJob;

  private boolean _validateTemplatesAtAll;
  private boolean _validateTemplatesNow;
  private int _buildKind;
  private boolean _threadedBuild;

  static {
    WodBuilder._validationJob = new ValidationProgressJob();
    WodBuilder.validationThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
  }

  public WodBuilder() {
    super();
  }

  public boolean isEnabled() {
    return true;
  }

  // MS: This should probably move up to a higher level utility method
  protected static boolean getBooleanProperty(String propertiesKey, String preferencesKey, IProject project, IPreferenceStore preferenceStore) {
    boolean value;
    BuildProperties buildProperties = (BuildProperties) project.getAdapter(BuildProperties.class);
    String buildPropertiesValueStr = buildProperties.get(propertiesKey);
    if (buildPropertiesValueStr != null) {
      value = "true".equalsIgnoreCase(buildPropertiesValueStr);
    }
    else {
      String globalPropertiesValueStr = VariablesPlugin.getDefault().getGlobalVariables().getString(propertiesKey + "." + project.getName());
      if (globalPropertiesValueStr != null) {
        value = "true".equalsIgnoreCase(globalPropertiesValueStr);
      }
      else {
        value = preferenceStore.getBoolean(preferencesKey);
      }
    }
    return value;
  }

  public boolean buildStarted(int kind, Map args, IProgressMonitor monitor, IProject project, Map buildCache) {
    _buildKind = kind;
    if (getBooleanProperty("component.validateTemplates", PreferenceConstants.VALIDATE_TEMPLATES_KEY, project, Activator.getDefault().getPreferenceStore())) {
      _validateTemplatesAtAll = true;
      if (!getBooleanProperty("component.validateTemplatesOnBuild", PreferenceConstants.VALIDATE_TEMPLATES_ON_BUILD_KEY, project, Activator.getDefault().getPreferenceStore())) {
        _validateTemplatesNow = false;
      }
      else {
        _validateTemplatesNow = true;
      }
    }
    _threadedBuild = getBooleanProperty("component.threadedValidation", PreferenceConstants.THREADED_VALIDATION_KEY, project, Activator.getDefault().getPreferenceStore());
    if (kind == IncrementalProjectBuilder.FULL_BUILD) {
      WodParserCache.getModelGroupCache().clearCacheForProject(project);
      WodParserCache.getTypeCache().clearCacheForProject(project);
      WOHierarchyScope.clearCacheForProject(project);
    }
    return false;
  }

  public boolean buildPreparationDone(int kind, Map args, IProgressMonitor monitor, IProject project, Map buildCache) {
    return false;
  }

  public void handleClasses(IResource resource, IProgressMonitor monitor, Map buildCache) {
    // DO NOTHING
  }

  public void handleSource(IResource resource, IProgressMonitor progressMonitor, Map buildCache) {
    if (_validateTemplatesNow) {
      try {
        if (_buildKind == IncrementalProjectBuilder.INCREMENTAL_BUILD || _buildKind == IncrementalProjectBuilder.AUTO_BUILD) {
          ICompilationUnit compilationUnit = JavaCore.createCompilationUnitFrom((IFile) resource);
          if (compilationUnit != null) {
            IType type = compilationUnit.findPrimaryType();
            if (type != null) {
              IType woElementType = type.getJavaProject().findType("com.webobjects.appserver.WOElement", progressMonitor);
              if (woElementType != null) {
                ITypeHierarchy typeHierarchy = SuperTypeHierarchyCache.getTypeHierarchy(type, progressMonitor);
                if (typeHierarchy != null && typeHierarchy.contains(woElementType)) {
                  LocalizedComponentsLocateResult results = LocatePlugin.getDefault().getLocalizedComponentsLocateResult(resource);
                  IFile wodFile = results.getFirstWodFile();
                  if (wodFile != null && wodFile.exists()) {
                    wodFile.touch(progressMonitor);
                    validateWodFile(wodFile, progressMonitor);
                  }
                }
              }
            }
          }
        }
        // touchRelatedResources(_resource, _progressMonitor, _buildCache);
      }
      catch (Throwable t) {
        Activator.getDefault().log(t);
      }
    }
  }

  public void handleClasspath(IResource resource, IProgressMonitor monitor, Map buildCache) {
    // DO NOTHING
  }

  @SuppressWarnings("unchecked")
  protected Set<IContainer> componentBuildCache(Map buildCache) {
    Set<IContainer> builtComponents = (Set<IContainer>) buildCache.get("builtComponents");
    if (builtComponents == null) {
      builtComponents = new HashSet<IContainer>();
      buildCache.put("builtComponents", builtComponents);
    }
    return builtComponents;
  }

  public void handleOther(IResource resource, IProgressMonitor monitor, Map buildCache) {
    // ignore
  }

  protected boolean shouldValidate(IResource resource, Map buildCache) {
    boolean validate = false;
    Set<IContainer> builtComponents = componentBuildCache(buildCache);
    IContainer woFolder;
    if (resource instanceof IFile) {
      woFolder = resource.getParent();
    }
    else if (resource instanceof IContainer) {
      woFolder = (IContainer) resource;
    }
    else {
      woFolder = null;
    }
    if (woFolder != null && !builtComponents.contains(woFolder)) {
      validate = true;
      builtComponents.add(woFolder);
    }
    return validate;
  }

  public void handleWebServerResources(IResource resource, IProgressMonitor monitor, Map buildCache) {
    // DO NOTHING
  }

  public void handleWoappResources(IResource resource, IProgressMonitor monitor, Map buildCache) {
    if (_validateTemplatesNow) {
      try {
        boolean validate = false;
        if (resource instanceof IFile) {
          if (resource.getParent().getName().endsWith(".wo")) {
            IFile file = (IFile) resource;
            String fileExtension = file.getFileExtension();
            if ("wod".equals(fileExtension)) {
              validate = shouldValidate(file, buildCache);
            }
            else if ("html".equals(fileExtension)) {
              validate = shouldValidate(file, buildCache);
            }
            else if ("api".equals(fileExtension)) {
              // should we really do something with the component when
              // we change the api?
              // shoulnd't we validate all files using the api?
              validate = false;
            }
            else if ("woo".equals(fileExtension)) {
              validate = shouldValidate(file, buildCache);
            }
          }
        }
        else if (resource instanceof IContainer) {
          IContainer folder = (IContainer) resource;
          String fileExtension = folder.getFileExtension();
          if ("wo".equals(fileExtension)) {
            validate = shouldValidate(folder, buildCache);
          }
        }

        if (validate) {
          validateWodFile(resource, monitor);
        }
      }
      catch (Throwable e) {
        Activator.getDefault().log(e);
      }
    }
    else if (!_validateTemplatesAtAll || (_buildKind == IncrementalProjectBuilder.FULL_BUILD || _buildKind == IncrementalProjectBuilder.CLEAN_BUILD)) {
      if (resource instanceof IFile) {
        IFile file = (IFile) resource;
        String fileExtension = file.getFileExtension();
        if ("wod".equals(fileExtension)) {
          WodModelUtils.deleteProblems(file);
        }
        else if ("html".equals(fileExtension)) {
          WodModelUtils.deleteProblems(file);
        }
        else if ("woo".equals(fileExtension)) {
          WodModelUtils.deleteProblems(file);
        }
      }
      else if (resource instanceof IContainer) {
        IContainer folder = (IContainer) resource;
        String fileExtension = folder.getFileExtension();
        if ("wo".equals(fileExtension)) {
          String componentName = folder.getName().substring(0, folder.getName().lastIndexOf('.'));
          WodModelUtils.deleteProblems(folder.getFile(new Path(componentName + ".html")));
          WodModelUtils.deleteProblems(folder.getFile(new Path(componentName + ".wod")));
          WodModelUtils.deleteProblems(folder.getFile(new Path(componentName + ".woo")));
        }
      }
    }
  }

  protected void validateWodFile(IResource resource, IProgressMonitor progressMonitor) {
    // System.out.println("WodBuilder.validateWodFile: " + resource);
    WodBuilder.validateComponent(resource, _threadedBuild, progressMonitor);
  }

  public static void validateComponent(IResource resource, boolean threaded, IProgressMonitor progressMonitor) {
    if (threaded) {
      WodBuilder.validationThreadPool.execute(new ValidatingComponent(resource, progressMonitor));
    }
    else {
      WodBuilder._validateComponent(resource, progressMonitor, true);
    }
  }

  public static void _validateComponent(IResource resource, IProgressMonitor progressMonitor, boolean showProgress) {
    if (resource != null) {
      // System.out.println("WodBuilder._validateComponent: " + resource);
      String resourceName = resource.getName();
      if (progressMonitor != null) {
        if (showProgress) {
          progressMonitor.subTask("Locating components for " + resourceName + " ...");
        }
      }
      try {
        WodParserCache cache = WodParserCache.parser(resource);
        if (progressMonitor != null && cache.getWodEntry().getFile() != null) {
          if (showProgress) {
            progressMonitor.subTask("Building WO " + cache.getWodEntry().getFile().getName() + " ...");
          }
        }
        cache.clearParserCache();
        cache.parse();
        cache.validate(true, false);
      }
      catch (Throwable t) {
        t.printStackTrace();
      }
      // System.out.println("WodBuilder._validateComponent: done with " +
      // resource);
    }
  }

  public static class ValidationProgressJob extends Job {
    private ConcurrentLinkedQueue<IResource> _validatingResources;
    private Object _lock = new Object();

    public ValidationProgressJob() {
      super("Component Validation");
      setPriority(Job.LONG);
      setUser(false);
      // setProperty(IProgressConstants.ICON_PROPERTY, getImage());

      _validatingResources = new ConcurrentLinkedQueue<IResource>();
    }

    public void start(IResource resource) {
      _validatingResources.add(resource);
      WOHierarchyScope.incrementReferenceCountForProject(resource.getProject());
      synchronized (_lock) {
        _lock.notifyAll();
      }
      schedule();
    }

    public void finish(IResource resource) {
      _validatingResources.remove(resource);
      WOHierarchyScope.decrementReferenceCountForProject(resource.getProject());
      synchronized (_lock) {
        _lock.notifyAll();
      }
    }

    @Override
    protected IStatus run(IProgressMonitor monitor) {
      IStatus status = null;
      long completedAtStart = ((ThreadPoolExecutor) WodBuilder.validationThreadPool).getCompletedTaskCount();
      while (!monitor.isCanceled() && status == null) {
        synchronized (_lock) {
          if (_validatingResources.size() == 0) {
            monitor.done();
            status = Status.OK_STATUS;
          }
          else {
            setName("Component Validation");

            try {
              _lock.wait();
            }
            catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }

        if (_validatingResources.size() > 0 && !monitor.isCanceled()) {
          monitor.beginTask("Validating ...", IProgressMonitor.UNKNOWN);
          StringBuffer sb = new StringBuffer();
          sb.append("Validating ");
          Iterator<IResource> resourceIter = _validatingResources.iterator();
          while (resourceIter.hasNext()) {
            IResource resource = resourceIter.next();
            sb.append(resource.getName());
            if (resourceIter.hasNext()) {
              sb.append(", ");
            }
          }

          long taskCount = ((ThreadPoolExecutor) WodBuilder.validationThreadPool).getTaskCount() - completedAtStart;
          long completedTaskCount = ((ThreadPoolExecutor) WodBuilder.validationThreadPool).getCompletedTaskCount() - completedAtStart;
          sb.append(" (" + completedTaskCount + " of " + taskCount + ")");
         
          sb.append("...");
          monitor.setTaskName(sb.toString());

          monitor.beginTask(sb.toString(), (int) taskCount);
          monitor.worked((int) completedTaskCount);
        }
      }
      return monitor.isCanceled() ? Status.CANCEL_STATUS : status;
    }
  }

  public static class ValidatingComponent implements Runnable {
    private IResource _resource;
    private IProgressMonitor _monitor;

    public ValidatingComponent(IResource resource, IProgressMonitor monitor) {
      _resource = resource;
      _monitor = monitor;
    }

    public void run() {
      if (_monitor == null || !_monitor.isCanceled()) {
        _validationJob.start(_resource);
        try {
          WodBuilder._validateComponent(_resource, _monitor, false);
        }
        finally {
          _validationJob.finish(_resource);
        }
      }
      else {
        // System.out.println("BuildingComponent.run: cancelled " + _resource);
      }
    }
  }
}
TOP

Related Classes of org.objectstyle.wolips.wodclipse.core.builder.WodBuilder$ValidatingComponent

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.