Author: tfmorris Date: 2010-04-13 10:58:32-0700 New Revision: 18257 Modified: trunk/src/argouml-app/src/org/argouml/profile/Profile.java trunk/src/argouml-app/src/org/argouml/profile/UserDefinedProfile.java trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileMeta.java trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileUML.java
Log: Lazy load models and critics Modified: trunk/src/argouml-app/src/org/argouml/profile/Profile.java Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/profile/Profile.java?view=diff&pathrev=18257&r1=18256&r2=18257 ============================================================================== --- trunk/src/argouml-app/src/org/argouml/profile/Profile.java (original) +++ trunk/src/argouml-app/src/org/argouml/profile/Profile.java 2010-04-13 10:58:32-0700 @@ -1,13 +1,14 @@ /* $Id$ ***************************************************************************** - * Copyright (c) 2009 Contributors - see below + * Copyright (c) 2007,2010 Contributors - see below * 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: - * tfmorris + * maurelio1234 - Initial implementation + * Tom Morris ***************************************************************************** * * Some portions of this file was previously release using the BSD License: @@ -38,17 +39,23 @@ package org.argouml.profile; -import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.argouml.cognitive.Critic; /** - * Abstract class representing a Profile. It contains default types and + * Abstract class representing an ArgoUML Profile. It contains default types and * presentation characteristics that can be tailored to various modeling * environments. + * <p> + * An ArgoUML Profile consists of:<ul> + * <li>a UML profile (a special type of UML Model) + * <li>a set of ArgoUML Critics + * <li>a set of default types for parameters, etc + * <li>presentation characteristics for ... * * @author maurelio1234 */ @@ -143,10 +150,22 @@ * @throws ProfileException if failed to get profile. */ public Collection getProfilePackages() throws ProfileException { - return new ArrayList(); + return Collections.emptyList(); } /** + * Get just those top level profile packages which have been loaded into the + * model repository. Primarily for internal use. Applications should use + * {...@link #getProfilePackages()}. + * + * @return collection of top level UML profile packages. + * @throws ProfileException if failed to get profile. + */ + public Collection getLoadedPackages() throws ProfileException { + return getProfilePackages(); + } + + /** * @return the display name */ @Override Modified: trunk/src/argouml-app/src/org/argouml/profile/UserDefinedProfile.java Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/profile/UserDefinedProfile.java?view=diff&pathrev=18257&r1=18256&r2=18257 ============================================================================== --- trunk/src/argouml-app/src/org/argouml/profile/UserDefinedProfile.java (original) +++ trunk/src/argouml-app/src/org/argouml/profile/UserDefinedProfile.java 2010-04-13 10:58:32-0700 @@ -1,12 +1,13 @@ /* $Id$ ***************************************************************************** - * Copyright (c) 2009-2010 Contributors - see below + * Copyright (c) 2007,2010 Contributors - see below * 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: + * maurelio1234 - Initial implementation * thn * euluis ***************************************************************************** @@ -48,6 +49,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -84,11 +86,17 @@ private File modelFile; - private Collection profilePackages; + private Collection profilePackages = null; private UserDefinedFigNodeStrategy figNodeStrategy = new UserDefinedFigNodeStrategy(); + private ProfileReference reference; + + private ProfileManager profileManager; + + private boolean criticsLoaded = false; + private class UserDefinedFigNodeStrategy implements FigNodeStrategy { private Map<String, Image> images = new HashMap<String, Image>(); @@ -117,7 +125,7 @@ private int length; /** - * @return if this descriptor ir valid + * @return if this descriptor is valid */ public boolean isValid() { return stereotype != null && src != null && length > 0; @@ -137,16 +145,13 @@ LOG.info("load " + file); displayName = file.getName(); modelFile = file; - ProfileReference reference = null; try { reference = new UserProfileReference(file.getPath()); } catch (MalformedURLException e) { throw new ProfileException( "Failed to create the ProfileReference.", e); } - profilePackages = new FileModelLoader().loadModel(reference); - - finishLoading(manager); + profileManager = manager; } /** @@ -226,10 +231,8 @@ public UserDefinedProfile(URL url, ProfileManager manager) throws ProfileException { LOG.info("load " + url); - ProfileReference reference = null; reference = new UserProfileReference(url.getPath(), url); - profilePackages = new URLModelLoader().loadModel(reference); - finishLoading(manager); + profileManager = manager; } /** @@ -247,7 +250,9 @@ } /** - * A constructor that reads a file from an URL associated with some profiles + * A constructor that reads a file from an URL associated with some + * profiles. Designed for use with URLs which represent entries in a + * JAR or Zip file. * * @param dn the display name of the profile * @param url the URL of the profile mode @@ -263,21 +268,14 @@ LOG.info("load " + url); this.displayName = dn; - if (url != null) { - ProfileReference reference = null; - reference = new UserProfileReference(url.getPath(), url); - profilePackages = new URLModelLoader().loadModel(reference); - } else { - profilePackages = new ArrayList(0); - } + reference = new UserProfileReference(url.getPath(), url); this.setCritics(critics); for (String profileID : dependencies) { addProfileDependency(profileID); } - - finishLoading(manager); + profileManager = manager; } /** @@ -311,61 +309,97 @@ * @param manager the profile manager which will be used to resolve * dependencies */ - private void finishLoading(ProfileManager manager) { - Collection packagesInProfile = filterPackages(); - - for (Object obj : packagesInProfile) { - // if there is only one package in the model, we should suppose it's - // the profile model, if there is more than one, we take the ones - // marked as <<profile>> - if (Model.getFacade().isAModelElement(obj) - && (Model.getFacade().isAProfile(obj) - || (packagesInProfile.size() == 1))) { - - // load profile name - String name = Model.getFacade().getName(obj); - if (name != null) { - displayName = name; + private void loadModel() { + if (profilePackages == null) { + try { + if (modelFile != null) { + profilePackages = new FileModelLoader().loadModel(reference); } else { - if (displayName == null) { - displayName = Translator - .localize("misc.profile.unnamed"); - } + profilePackages = new URLModelLoader().loadModel(reference); } - LOG.info("profile " + displayName); + } catch (ProfileException e1) { + LOG.error("Exception loading profile " + reference.getPath(), + e1); + return; + } - if (Model.getFacade().getUmlVersion().charAt(0) == '1') { - // load profile dependencies - String dependencyListStr = Model.getFacade() - .getTaggedValueValue(obj, "Dependency"); - StringTokenizer st = new StringTokenizer(dependencyListStr, - " ,;:"); - - String dependencyName = null; - - while (st.hasMoreTokens()) { - dependencyName = st.nextToken(); - if (dependencyName != null) { - LOG.debug("Adding dependency " + dependencyName); - Profile profile = - manager.lookForRegisteredProfile( - dependencyName); - if (profile != null) { - addProfileDependency(profile); - } else { - LOG.warn("The profile \"" + displayName - + "\" has a dependency named \"" - + dependencyName - + "\" which isn't solvable."); - } + Collection packagesInProfile = filterPackages(profilePackages); + + for (Object obj : packagesInProfile) { + // if there is only one package in the model, we should suppose it's + // the profile model, if there is more than one, we take the ones + // marked as <<profile>> + if (Model.getFacade().isAModelElement(obj) + && (Model.getFacade().isAProfile(obj) + || (packagesInProfile.size() == 1))) { + + // load profile name + String name = Model.getFacade().getName(obj); + if (name != null) { + displayName = name; + } else { + if (displayName == null) { + displayName = Translator + .localize("misc.profile.unnamed"); } } + LOG.info("profile " + displayName); + + loadDependentProfiles(obj); + } + } + + loadFigNodes(packagesInProfile); + } + } + + + private void loadDependentProfiles(Object obj) { + if (Model.getFacade().getUmlVersion().charAt(0) == '1') { + loadDependentProfilesUml1(obj); + } + // TODO: profile dependencies for UML2 + } + + + /** + * For ArgoUML UML 1.4 profiles dependencies are encoded as a list of + * profile names in the TaggedValue named "Dependency" on the profile pkg. + * + * @param pkg profile package + */ + private void loadDependentProfilesUml1(Object pkg) { + // load profile dependencies + String dependencyListStr = Model.getFacade().getTaggedValueValue(pkg, + "Dependency"); + StringTokenizer st = new StringTokenizer(dependencyListStr, " ,;:"); + + String dependencyName = null; + + while (st.hasMoreTokens()) { + dependencyName = st.nextToken(); + if (dependencyName != null) { + LOG.debug("Adding dependency " + dependencyName); + Profile profile = profileManager + .lookForRegisteredProfile(dependencyName); + if (profile != null) { + addProfileDependency(profile); + } else { + LOG.warn("The profile \"" + displayName + + "\" has a dependency named \"" + dependencyName + + "\" which isn't solvable."); } - // TODO: profile dependencies for UML2 } } + } - // load fig nodes + + /** + * Load FigNodes from profile packages. + * + * @param packagesInProfile + */ + private void loadFigNodes(Collection packagesInProfile) { Collection allStereotypes = Model.getExtensionMechanismsHelper() .getStereotypes(packagesInProfile); for (Object stereotype : allStereotypes) { @@ -395,23 +429,32 @@ } } } - - // load critiques - Set<Critic> myCritics = this.getCritics(); - myCritics.addAll(getAllCritiquesInModel()); - this.setCritics(myCritics); } + @Override + public Set<Critic> getCritics() { + if (!criticsLoaded ) { + Set<Critic> myCritics = super.getCritics(); + myCritics.addAll(getAllCritiquesInModel()); + this.setCritics(myCritics); + criticsLoaded = true; + } + return super.getCritics(); + } + /** * @return the packages in the <code>profilePackages</code> */ - private Collection filterPackages() { + private Collection filterPackages(Collection packages) { Collection ret = new ArrayList(); - for (Object object : profilePackages) { + + // TODO: All this profile loading/handling needs to move someplace in model subsystem probably + + for (Object object: packages) { if (Model.getFacade().isAPackage(object)) { if (Model.getFacade().isAProfile(object)) { object = Model.getExtensionMechanismsHelper() - .makeProfileApplicable(object); + .makeProfileApplicable(object); } ret.add(object); } @@ -606,10 +649,11 @@ return decision; } + // TODO: Is this (critics embedded in comments) actually used by anyone? private List<CrOCL> getAllCritiquesInModel() { List<CrOCL> ret = new ArrayList<CrOCL>(); - Collection<Object> comments = getAllCommentsInModel(profilePackages); + Collection<Object> comments = getAllCommentsInModel(getProfilePackages()); for (Object comment : comments) { if (Model.getExtensionMechanismsHelper().hasStereotype(comment, @@ -645,6 +689,9 @@ * @return the string that should represent this profile in the GUI. */ public String getDisplayName() { + // TODO: Seems like overkill to load the model just to get the display + // name, but that's where it's stored currently - tfm + loadModel(); return displayName; } @@ -686,9 +733,19 @@ @Override public Collection getProfilePackages() { + loadModel(); return profilePackages; } - + + @Override + public Collection getLoadedPackages() { + if (profilePackages == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableCollection(profilePackages); + } + } + private FigNodeDescriptor loadImage(String stereotype, File f) throws IOException { FigNodeDescriptor descriptor = new FigNodeDescriptor(); Modified: trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileMeta.java Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileMeta.java?view=diff&pathrev=18257&r1=18256&r2=18257 ============================================================================== --- trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileMeta.java (original) +++ trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileMeta.java 2010-04-13 10:58:32-0700 @@ -1,12 +1,13 @@ /* $Id$ ***************************************************************************** - * Copyright (c) 2009 Contributors - see below + * Copyright (c) 2008,2010 Contributors - see below * 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: + * maas - Initial implementation * tfmorris ***************************************************************************** * @@ -41,9 +42,11 @@ import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Set; +import org.apache.log4j.Logger; import org.argouml.cognitive.Critic; import org.argouml.cognitive.ToDoItem; import org.argouml.model.Model; @@ -64,9 +67,14 @@ */ public class ProfileMeta extends Profile { + private static final Logger LOG = Logger.getLogger(ProfileMeta.class); + private static final String PROFILE_FILE = "metaprofile.xmi"; - - private Collection model; + private ProfileReference profileReference = null; + + private Collection model = null; + + Set<Critic> critics = null; /** * Creates a new instance of this profile @@ -75,26 +83,34 @@ */ @SuppressWarnings("unchecked") public ProfileMeta() throws ProfileException { - ProfileModelLoader profileModelLoader = new ResourceModelLoader(); - ProfileReference profileReference = null; + super(); try { profileReference = new CoreProfileReference(PROFILE_FILE); } catch (MalformedURLException e) { throw new ProfileException( "Exception while creating profile reference.", e); } - model = profileModelLoader.loadModel(profileReference); + } + private Collection getModel() { if (model == null) { - model = new ArrayList(); - model.add(Model.getModelManagementFactory().createModel()); + ProfileModelLoader profileModelLoader = new ResourceModelLoader(); + try { + model = profileModelLoader.loadModel(profileReference); + } catch (ProfileException e) { + LOG.error("Exception loading metaprofile " + PROFILE_FILE, e); + } + + if (model == null) { + model = new ArrayList(); + model.add(Model.getModelManagementFactory().createModel()); + } } - - loadWellFormednessRules(); + return model; } private void loadWellFormednessRules() { - Set<Critic> critics = new HashSet<Critic>(); + critics = new HashSet<Critic>(); try { critics.add(new CrOCL("context ModelElement inv: " @@ -158,7 +174,25 @@ @Override public Collection getProfilePackages() throws ProfileException { - return model; + return Collections.unmodifiableCollection(getModel()); } + + @Override + public Collection<Object> getLoadedPackages() { + if (model == null) { + return Collections.emptyList(); + } else { + return Collections.unmodifiableCollection(model); + } + } + + @Override + public Set<Critic> getCritics() { + if (critics == null) { + loadWellFormednessRules(); + } + return super.getCritics(); + } + } Modified: trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileUML.java Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileUML.java?view=diff&pathrev=18257&r1=18256&r2=18257 ============================================================================== --- trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileUML.java (original) +++ trunk/src/argouml-app/src/org/argouml/profile/internal/ProfileUML.java 2010-04-13 10:58:32-0700 @@ -1,13 +1,15 @@ /* $Id$ ***************************************************************************** - * Copyright (c) 2009 Contributors - see below + * Copyright (c) 2008,2010 Contributors - see below * 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: + * maurelio1234 - Initial implementation * thn + * Tom Morris - lazy loading ***************************************************************************** * * Some portions of this file was previously release using the BSD License: @@ -41,9 +43,11 @@ import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.Set; +import org.apache.log4j.Logger; import org.argouml.cognitive.Critic; import org.argouml.cognitive.ToDoItem; import org.argouml.cognitive.Translator; @@ -98,6 +102,8 @@ */ public class ProfileUML extends Profile { + private static final Logger LOG = Logger.getLogger(ProfileUML.class); + private static final String PROFILE_UML14_FILE = "default-uml14.xmi"; private static final String PROFILE_UML22_FILE = "default-uml22.xmi"; @@ -107,7 +113,11 @@ private FormatingStrategy formatingStrategy; private ProfileModelLoader profileModelLoader; private Collection model; - + + private Set<Critic> critics = null; + + private ProfileReference profileReference = null; + /** * Construct a Profile for UML modeling. * @throws ProfileException @@ -115,8 +125,6 @@ @SuppressWarnings("unchecked") ProfileUML() throws ProfileException { formatingStrategy = new FormatingStrategyUML(); - profileModelLoader = new ResourceModelLoader(); - ProfileReference profileReference = null; try { if (Model.getFacade().getUmlVersion().charAt(0) == '1') { profileReference = @@ -131,22 +139,31 @@ throw new ProfileException( "Exception while creating profile reference.", e); } - model = profileModelLoader.loadModel(profileReference); + } + private Collection getModel() { if (model == null) { - model = new ArrayList(); - model.add(Model.getModelManagementFactory().createProfile()); - } - - for (Object p : model) { - Model.getExtensionMechanismsHelper().makeProfileApplicable(p); + profileModelLoader = new ResourceModelLoader(); + try { + model = profileModelLoader.loadModel(profileReference); + } catch (ProfileException e) { + LOG.error("Error loading UML profile", e); + } + + if (model == null) { + model = new ArrayList(); + model.add(Model.getModelManagementFactory().createProfile()); + } + + for (Object p : model) { + Model.getExtensionMechanismsHelper().makeProfileApplicable(p); + } } - - loadWellFormednessRules(); + return model; } private void loadWellFormednessRules() { - Set<Critic> critics = new HashSet<Critic>(); + critics = new HashSet<Critic>(); critics.add(new CrAssocNameConflict()); critics.add(new CrAttrNameConflict()); @@ -456,14 +473,32 @@ @Override + public Set<Critic> getCritics() { + if (critics == null) { + loadWellFormednessRules(); + } + return super.getCritics(); + } + + @Override public Collection getProfilePackages() { - return model; + return Collections.unmodifiableCollection(getModel()); } @Override + public Collection<Object> getLoadedPackages() { + if (model == null) { + return Collections.emptyList(); + } else { + return Collections.unmodifiableCollection(model); + } + } + + @Override public DefaultTypeStrategy getDefaultTypeStrategy() { return new DefaultTypeStrategy() { + private Collection model = getModel(); public Object getDefaultAttributeType() { return ModelUtils.findTypeInModel("Integer", model.iterator() .next()); ------------------------------------------------------ http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=2581072 To unsubscribe from this discussion, e-mail: [[email protected]].
