Package org.openiaml.model.codegen.php

Source Code of org.openiaml.model.codegen.php.OawCodeGenerator

/**
*
*/
package org.openiaml.model.codegen.php;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.openarchitectureware.workflow.WorkflowRunner;
import org.openarchitectureware.workflow.util.ProgressMonitorAdapter;
import org.openiaml.model.codegen.ICodeGenerator;
import org.openiaml.model.codegen.ICodeGeneratorInMemory;
import org.openiaml.model.model.Value;

/**
* @author jmwright
*
*/
public class OawCodeGenerator implements ICodeGenerator, ICodeGeneratorInMemory {
 
  public static final String PLUGIN_ID = "org.openiaml.model.codegen.php";
   
  /**
   * <p>Execute the workflow in the given workflow file.
   * By default, this creates a new {@link WorkflowRunner} and then
   * calls {@link WorkflowRunner#run(String, org.openarchitectureware.workflow.monitor.ProgressMonitor, Map, Map)}.
   * </p>
   *
   * <p>This method is extracted so it can be overridden if necessary.</p>
   *
   * @param wfFile
   * @param monitor
   * @param properties
   * @param slotContents
   */
  protected void executeWorkflow(String wfFile, IProgressMonitor monitor, Map<String, String> properties, Map<String, ?> slotContents) {
    new WorkflowRunner().run(wfFile,
        new ProgressMonitorAdapter(monitor), properties, slotContents);
   
  }

  /**
   * Guess how many files we are going to create.
   * We will just guess '100'.
   *
   * <p>TODO perhaps we could estimate the number of files from the size of the already-loaded model?
   *
   * @param model
   * @return
   */
  protected int guessNumberOfFilesToCreate(EObject model) {
    return 100;
  }

  /**
   * <p>
   * Construct a RuntimeException with the given message, and throw it.
   * Useful in templates, as we can get a stack trace to problems, rather
   * than using OAW's ERROR code, which only prints out text.
   * </p>
   *
   * <p>
   * This includes a workaround for an OAW problem, where an exception thrown during
   * workflow execution is renamed a WorkflowInterruption, and the causing exception is
   * lost when saved to the error log. Our workaround is to serialise this exception
   * into a special map ({@link #getExceptionForKey(String)}, which can then be unserialised
   * by the log when it receives the error log message.
   * </p>
   *
   * <p>
   * This workaround is saved in the thrown exception message, as "[original message] @key:[generated key]".
   * The original exception can be retrieved through {@link #getExceptionForKey(String)}.
   * </p>
   *
   * @param message
   */
  public static void throwException(String message) {
    Throwable e = new RuntimeException(message);
    String key = generateExceptionKey();
    keyToExceptionMap.put(key, e);
    throw new RuntimeException(e.getMessage() + " @key:" + key, e);
  }

  /**
   * Generate a new exception key.
   *
   * @return
   */
  private static String generateExceptionKey() {
    keyToExceptionCount++;
    return "ex" + keyToExceptionCount;
  }

  public static Map<String,Throwable> keyToExceptionMap;
  public static int keyToExceptionCount;
 
  public static void resetKeyToExceptionMap() {
    keyToExceptionMap = new HashMap<String,Throwable>();
    keyToExceptionCount = 0;
  }
 
  public static Throwable getExceptionForKey(String key) {
    return keyToExceptionMap.get(key);
  }
 
  /**
   * Get the exception for a given message. If no exception exists,
   * null is returned.
   *
   * @param message
   * @return
   */
  public static Throwable getExceptionForMessage(String message) {
    if (message.indexOf("@key:") < 0) {
      return null;
    }
    String key = message.substring(message.indexOf("@key:") + "@key:".length());
    // remove trailing whitespace
    if (key.indexOf(" ") >= 0) {
      key = key.substring(0, key.indexOf(" "));
    }
    if (key.indexOf("\r") >= 0) {
      key = key.substring(0, key.indexOf("\r"));
    }
    if (key.indexOf("\n") >= 0) {
      key = key.substring(0, key.indexOf("\n"));
    }
    if (key.indexOf("\t") >= 0) {
      key = key.substring(0, key.indexOf("\t"));
    }
    return keyToExceptionMap.get(key);
  }
 
  /**
   * Does the given EObject have an {@link EAttribute} 'name' that can be
   * overridden with a new {@link Value}?
   *
   * @param object the EObject to check (checks the {@link EObject#eClass() EClass})
   * @param name the property name to check
   * @return true only if the given property name exists, and is an {@link EAttribute}
   */
  public static boolean isValidValueName(EObject object, String name) {
    EStructuralFeature f = object.eClass().getEStructuralFeature(name);
    if (f == null)
      return false;
   
    // only EAttributes can be overridden as properties
    return f instanceof EAttribute;
  }
 
  /**
   * Get the current version of the IAML code generation platform.
   * This is obtained from the version returned by the Bundle.
   *
   * @return the current version of the IAML code generation platform
   */
  public static String getIamlVersion() {
    return IAMLPHPCodegenPlugin.getDefault().getBundle().getVersion().toString();
  }
 
  /*
   * @see org.openiaml.model.codegen.ICodeGeneratorInMemory#generateCode(org.eclipse.emf.ecore.EObject, org.eclipse.core.runtime.IProgressMonitor, java.util.Map)
   */
  @Override
  public IStatus generateCode(EObject model, IProject project, IProgressMonitor monitor,
      Map<String, String> runtimeProperties) {
     
    // reset exception-key map
    resetKeyToExceptionMap();
   
    // we need to guess how many files this method will create,
    // so we can try and have some sort of progress monitor.
    int filesToCreate = guessNumberOfFilesToCreate(model);
   
    monitor.beginTask("Generating code from in-memory model", filesToCreate * 2);
   
    /*
     * We have to do some magic to enable OAW logging to go through
     * our own class. We have to provide this information to
     * commons.logging directly.
     *
     * Based on http://oaw-forum.itemis.de/forum/viewtopic.php?forum=1&showtopic=1486 (german)
     */
    ClassLoader oldcl = Thread.currentThread().getContextClassLoader();
   
    try {
      // to enable custom logging
      Thread.currentThread().setContextClassLoader(OawCodeGenerator.class.getClassLoader());
      CustomOAWLog.registerToLogFactory();
     
      // notify the logger of our monitor, so we can keep track
      // of created files
      CustomOAWLog.setMonitor(monitor);
     
      String wfFile = "src/workflow/runtime-memory.oaw";
      Map<String,String> properties = new HashMap<String,String>();
      properties.put("src-gen", project.getLocation().toString())// have to get absolute filename for output dir
      properties.put("config_runtime", runtimeProperties.get("config_runtime"));
      properties.put("config_web", runtimeProperties.get("config_web"));
      properties.put("debug", Boolean.toString(Boolean.parseBoolean(runtimeProperties.get("debug"))));
      properties.put("email_handler", runtimeProperties.get("email_handler"));
      properties.put("email_handler_phpmailer_include", runtimeProperties.get("email_handler_phpmailer_include"));
      properties.put("email_handler_file_destination", runtimeProperties.get("email_handler_file_destination"));
      properties.put("map_handler", runtimeProperties.get("map_handler"));
      properties.put("proxy_host", runtimeProperties.get("proxy_host"));
      properties.put("proxy_port", runtimeProperties.get("proxy_port"));
      properties.put("proxy_userpass", runtimeProperties.get("proxy_userpass"));
      properties.put("google_maps_api_key", runtimeProperties.get("google_maps_api_key"));
     
      Map<String,Object> slotContents = new HashMap<String,Object>();

      // load the model into the static slot
      CurrentModel.setCurrentModel(model);
     
      if (monitor.isCanceled())
        return Status.CANCEL_STATUS;

      try {
        IACleanerBeautifier.setMonitor(monitor);
        executeWorkflow(wfFile, monitor, properties, slotContents);
      } catch (OperationCanceledException e) {
        // monitor was cancelled; OK
      } finally {
        IACleanerBeautifier.setMonitor(null);
      }

      if (monitor.isCanceled())
        return Status.CANCEL_STATUS;

      // refresh output folder
      try {
        project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, filesToCreate));
      } catch (CoreException e) {
        return new Status(Status.WARNING, PLUGIN_ID, "Could not refresh local project", e);
      }
     
      if (CustomOAWLog.hasErrors()) {
        return CustomOAWLog.getErrors();
      }
      return Status.OK_STATUS;
    } finally {
      // reset the classloader/log
      Thread.currentThread().setContextClassLoader(oldcl);
      CustomOAWLog.unregisterFromLogFactory();
     
      // remove the loaded model
      CurrentModel.setCurrentModel(null);
     
      // the monitor is done
      monitor.done();
    }

  }

 
}
TOP

Related Classes of org.openiaml.model.codegen.php.OawCodeGenerator

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.