Package org.springframework.ide.eclipse.aop.core.internal.model

Source Code of org.springframework.ide.eclipse.aop.core.internal.model.AopReferenceModelPeristence

/*******************************************************************************
* Copyright (c) 2007, 2008 Spring IDE Developers
* 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
*
* Contributors:
*     Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.aop.core.internal.model;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.XMLMemento;
import org.springframework.ide.eclipse.aop.core.Activator;
import org.springframework.ide.eclipse.aop.core.model.IAopProject;
import org.springframework.ide.eclipse.aop.core.model.IAopReference;
import org.springframework.ide.eclipse.aop.core.model.IAopReferenceModel;
import org.springframework.ide.eclipse.aop.core.model.IAspectDefinition;
import org.springframework.ide.eclipse.aop.core.util.AopReferenceModelMarkerUtils;

/**
* @author Christian Dupuis
* @since 2.0
*/
public class AopReferenceModelPeristence {

  private static final Map<String, IElementFactory> ELEMENT_FACTORIES;

  static {
    ELEMENT_FACTORIES = new HashMap<String, IElementFactory>();
    ELEMENT_FACTORIES.put(AnnotationAspectDefinitionElementFactory.FACTORY_ID,
        new AnnotationAspectDefinitionElementFactory());
    ELEMENT_FACTORIES.put(AnnotationIntroductionDefinitionElementFactory.FACTORY_ID,
        new AnnotationIntroductionDefinitionElementFactory());
    ELEMENT_FACTORIES.put(BeanAspectDefinitionElementFactory.FACTORY_ID,
        new BeanAspectDefinitionElementFactory());
    ELEMENT_FACTORIES.put(BeanIntroductionDefinitionElementFactory.FACTORY_ID,
        new BeanIntroductionDefinitionElementFactory());
    ELEMENT_FACTORIES.put(JavaAdvisorDefinitionElementFactory.FACTORY_ID,
        new JavaAdvisorDefinitionElementFactory());
    ELEMENT_FACTORIES.put(AopReferenceElementFactory.FACTORY_ID,
        new AopReferenceElementFactory());
  }

  private static final String AOP_PROJECT_ELEMENT = "aop-project";

  private static final String AOP_REFERENCE_ELEMENT = "aop-reference";

  private static final String AOP_REFERENCE_MODEL_ELEMENT = "aop-reference-model";

  private static final String ASPECT_DEFINITION_ELEMENT = "aspect-definition";

  private static final String FACTORY_ID = "factory-id";

  private static final String NAME_ATTRIBUTE = "name";

  private IPath defaultFile = null;

  public AopReferenceModelPeristence() {
    this.defaultFile = Activator.getDefault().getStateLocation().append(".state");
  }

  private IMemento appendNewChild(IMemento memento, String type) {
    memento.createChild(type);
    IMemento[] ms = memento.getChildren(type);
    if (ms != null && ms.length > 0) {
      return ms[ms.length - 1];
    }
    return memento;
  }

  private void createAopProjects(IAopReferenceModel model, XMLMemento memento) {
    IMemento[] projects = memento.getChildren(AOP_PROJECT_ELEMENT);
    if (projects != null && projects.length > 0) {
      for (IMemento project : projects) {
        String projectName = project.getString(NAME_ATTRIBUTE);
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IResource member = root.findMember(projectName);
        if (member instanceof IProject) {
          IJavaProject javaProject = JavaCore.create((IProject) member);
          IAopProject aopProject = model.getProject(javaProject);

          createAspectDefinitions(projects, project, aopProject);

          // recreate the marker
          Set<IAopReference> references = aopProject.getAllReferences();
          for (IAopReference reference : references) {
            AopReferenceModelMarkerUtils.createMarker(reference, reference
                .getResource());
          }
        }
      }
    }
  }

  private void createAopReferences(IAopProject aopProject, IMemento aspectDefinitionM,
      IAspectDefinition aspectDefinition) {
    String factoryId;
    IMemento[] aopReferences = aspectDefinitionM.getChildren(AOP_REFERENCE_ELEMENT);
    if (aopReferences != null && aopReferences.length > 0) {
      for (IMemento aopReferenceM : aopReferences) {
        factoryId = aopReferenceM.getString(FACTORY_ID);
        IAopReference aopReference = (IAopReference) ELEMENT_FACTORIES.get(factoryId)
            .createElement(aopReferenceM);
        // The aopReference can be null if the resource has been deleted or is an external
        if (aopReference != null) {
          aopReference.setDefinition(aspectDefinition);
          aopProject.addAopReference(aopReference);
        }
      }
    }
  }

  private void createAspectDefinitions(IMemento[] projects, IMemento project,
      IAopProject aopProject) {
    IMemento[] aspectDefinitions = project.getChildren(ASPECT_DEFINITION_ELEMENT);
    if (projects != null && projects.length > 0) {
      for (IMemento aspectDefinitionM : aspectDefinitions) {
        String factoryId = aspectDefinitionM.getString(FACTORY_ID);
        IAspectDefinition aspectDefinition = (IAspectDefinition) ELEMENT_FACTORIES.get(
            factoryId).createElement(aspectDefinitionM);
        createAopReferences(aopProject, aspectDefinitionM, aspectDefinition);
      }
    }
  }

  protected boolean isPersisted() {
    return defaultFile.toFile().exists();
  }

  protected synchronized void loadReferenceModel() {
    if (!shouldModelByPersisted() || !isPersisted()) {
      return;
    }

    IAopReferenceModel model = Activator.getModel();
    Reader reader = null;
    try {
      reader = new FileReader(defaultFile.toFile());
      XMLMemento memento = XMLMemento.createReadRoot(reader);
      createAopProjects(model, memento);
    }
    catch (Exception e) {
      Activator.log("Cannot load .state model file", e);
      // re-init aop reference model
      Activator.getModel().clearProjects();
    }
    finally {
      if (reader != null) {
        try {
          reader.close();
        }
        catch (IOException e) {
        }
      }
    }
  }

  private boolean shouldModelByPersisted() {
    IScopeContext context = new InstanceScope();
    IEclipsePreferences node = context.getNode(Activator.PLUGIN_ID);
    return node.getBoolean(Activator.PERSIST_AOP_MODEL_PREFERENCE, true);
  }

  protected synchronized void saveReferenceModel() {
    if (!shouldModelByPersisted()) {
      if (isPersisted()) {
        defaultFile.toFile().delete();
      }
      return;
    }

    XMLMemento memento = XMLMemento.createWriteRoot(AOP_REFERENCE_MODEL_ELEMENT);
    Collection<IAopProject> projects = Activator.getModel().getProjects();
    for (IAopProject project : projects) {
      IMemento projectM = appendNewChild(memento, AOP_PROJECT_ELEMENT);
      projectM.putString(NAME_ATTRIBUTE, project.getProject().getElementName());

      Set<IAopReference> refs = project.getAllReferences();
      Map<IAspectDefinition, List<IAopReference>> maps = new HashMap<IAspectDefinition, List<IAopReference>>();
      for (IAopReference ref : refs) {
        if (maps.containsKey(ref.getDefinition())) {
          maps.get(ref.getDefinition()).add(ref);
        }
        else {
          List<IAopReference> r = new ArrayList<IAopReference>();
          r.add(ref);
          maps.put(ref.getDefinition(), r);
        }
      }

      for (Map.Entry<IAspectDefinition, List<IAopReference>> entry : maps.entrySet()) {
        IMemento definitionM = appendNewChild(projectM, ASPECT_DEFINITION_ELEMENT);
        if (entry.getKey() instanceof IAdaptable) {
          IPersistableElement pers = (IPersistableElement) ((IAdaptable) entry.getKey())
              .getAdapter(IPersistableElement.class);
          if (pers != null) {
            pers.saveState(definitionM);
            definitionM.putString(FACTORY_ID, pers.getFactoryId());
          }
          for (IAopReference ref : entry.getValue()) {
            if (ref instanceof IAdaptable) {
              IPersistableElement pers2 = (IPersistableElement) ((IAdaptable) ref)
                  .getAdapter(IPersistableElement.class);
              if (pers2 != null) {
                IMemento refM = appendNewChild(definitionM, AOP_REFERENCE_ELEMENT);
                pers2.saveState(refM);
                refM.putString(FACTORY_ID, pers2.getFactoryId());
              }
            }
          }
        }
      }
    }

    // save memento to default map file
    Writer writer = null;
    try {
      writer = new FileWriter(defaultFile.toFile());
      memento.save(writer);
    }
    catch (IOException e) {
    }
    finally {
      if (writer != null) {
        try {
          writer.flush();
          writer.close();
        }
        catch (IOException e) {
        }
      }
    }
  }
}
TOP

Related Classes of org.springframework.ide.eclipse.aop.core.internal.model.AopReferenceModelPeristence

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.