Java tutorial
/* * Copyright 2003 - 2016 The eFaps Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 org.efaps.update.version; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.apache.commons.digester3.Digester; import org.apache.commons.digester3.annotations.FromAnnotationsRuleModule; import org.apache.commons.digester3.annotations.rules.BeanPropertySetter; import org.apache.commons.digester3.annotations.rules.CallMethod; import org.apache.commons.digester3.annotations.rules.CallParam; import org.apache.commons.digester3.annotations.rules.ObjectCreate; import org.apache.commons.digester3.annotations.rules.SetNext; import org.apache.commons.digester3.annotations.rules.SetProperty; import org.apache.commons.digester3.binder.DigesterLoader; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.tools.ant.DirectoryScanner; import org.efaps.admin.program.esjp.EFapsClassLoader; import org.efaps.admin.runlevel.RunLevel; import org.efaps.ci.CIAdminCommon; import org.efaps.db.Context; import org.efaps.db.Insert; import org.efaps.db.Instance; import org.efaps.db.InstanceQuery; import org.efaps.db.QueryBuilder; import org.efaps.update.FileType; import org.efaps.update.Install; import org.efaps.update.Install.InstallFile; import org.efaps.update.Profile; import org.efaps.update.schema.program.esjp.ESJPCompiler; import org.efaps.update.schema.program.staticsource.AbstractStaticSourceCompiler; import org.efaps.update.util.InstallationException; import org.efaps.util.EFapsException; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author The eFaps Team * */ @ObjectCreate(pattern = "install") public final class Application { /** * Logging instance used to give logging information of this class. */ private static final Logger LOG = LoggerFactory.getLogger(Application.class); /** * Default Mapping of a a file extension to a Type for import and update. */ private static final Map<String, String> DEFAULT_TYPE_MAPPING = new HashMap<String, String>(); static { Application.DEFAULT_TYPE_MAPPING.put("bpmn2", FileType.BPM.getType()); Application.DEFAULT_TYPE_MAPPING.put("css", FileType.CSS.getType()); Application.DEFAULT_TYPE_MAPPING.put("java", FileType.JAVA.getType()); Application.DEFAULT_TYPE_MAPPING.put("js", FileType.JS.getType()); Application.DEFAULT_TYPE_MAPPING.put("jrxml", FileType.JRXML.getType()); Application.DEFAULT_TYPE_MAPPING.put("wiki", FileType.WIKI.getType()); Application.DEFAULT_TYPE_MAPPING.put("xml", FileType.XML.getType()); Application.DEFAULT_TYPE_MAPPING.put("xsl", FileType.XSL.getType()); } /** * Default list of includes used to evaluate the files to copy. * * @see #getFiles */ private static final Set<String> DEFAULT_INCLUDES = new HashSet<String>(); static { Application.DEFAULT_INCLUDES.add("**/*.bpmn2"); Application.DEFAULT_INCLUDES.add("**/*.css"); Application.DEFAULT_INCLUDES.add("**/*.java"); Application.DEFAULT_INCLUDES.add("**/*.js"); Application.DEFAULT_INCLUDES.add("**/*.jrxml"); Application.DEFAULT_INCLUDES.add("**/*.wiki"); Application.DEFAULT_INCLUDES.add("**/*.xml"); Application.DEFAULT_INCLUDES.add("**/*.xsl"); } /** * Default list of excludes used to evaluate the files to copy. * * @see #getFiles */ private static final Set<String> DEFAULT_EXCLUDES = new HashSet<String>(); static { Application.DEFAULT_EXCLUDES.add("**/versions.xml"); Application.DEFAULT_EXCLUDES.add("**/package-info.java"); Application.DEFAULT_EXCLUDES.add("**/.svn/**"); } /** * Stores the name of the application. * * @see #setApplication */ @BeanPropertySetter(pattern = "install/application") private String application = null; /** * Stores all versions of this application which must be installed. * * @see #getVersions() */ private final Set<ApplicationVersion> versions = new TreeSet<ApplicationVersion>(); /** * Install instance holding all XML definition / update files. * * @see #addURL(URL, String) */ private final Install install = new Install(); /** * Caches not stores versions (because if the kernel install is made, the * version could not be updated till the SQL tables and the data model is * already installed and the cache is reloaded). */ private final List<Long> notStoredVersions = new ArrayList<Long>(); /** * Stores the highest or maximum number of the versions to be installed. */ private Long maxVersion; /** * Project class path. * * @see #Application(URL, List) * @see #getClassPathElements() */ private List<String> classpathElements; /** * Dependencies to other applications for this application ordered. */ private final List<Dependency> dependencies = new ArrayList<Dependency>(); /** * Root URL where the source files are located. Could be a file directory ( * for local installation) or a jar file. * * @see #Application(URL, List) * @see #getRootUrl() */ private URL rootUrl; /** * Stores the name of the rootPackage. */ @SetProperty(pattern = "install/rootPackage", attributeName = "name") private String rootPackageName; /** * Used in combination with the digester. */ private Set<InstallFile> tmpElements = new HashSet<>(); /** * Initializes the {@link #rootUrl root URL} of this application. * * @param _rootUrl root URL of the source * @param _classpathElements elements of the class path * @see #rootUrl */ private Application(final URL _rootUrl, final List<String> _classpathElements) { this.rootUrl = _rootUrl; this.classpathElements = _classpathElements; } /** * Constructor used by Digester. */ public Application() { } /** * <code>null</code> is returned, of the version file could not be opened * and read. * * @param _versionUrl URL of the version file which defines the application * @param _rootUrl root URL where the source files are located (for local * files); URL of the class file (if source is in a Jar file) * @param _classpathElements elements of the class path * @return application instance with all version information * @throws InstallationException if version XML file could not be parsed */ public static Application getApplication(final URL _versionUrl, final URL _rootUrl, final List<String> _classpathElements) throws InstallationException { Application appl = null; try { final DigesterLoader loader = DigesterLoader.newLoader(new FromAnnotationsRuleModule() { @Override protected void configureRules() { bindRulesFrom(Application.class); } }); final Digester digester = loader.newDigester(); appl = (Application) digester.parse(_versionUrl); appl.rootUrl = _rootUrl; appl.classpathElements = _classpathElements; for (final InstallFile installFile : appl.tmpElements) { appl.install.addFile(installFile.setURL(new URL(_rootUrl, installFile.getName()))); } appl.tmpElements = null; Collections.sort(appl.dependencies, new Comparator<Dependency>() { @Override public int compare(final Dependency _dependency0, final Dependency _dependency1) { return _dependency0.getOrder().compareTo(_dependency1.getOrder()); } }); for (final ApplicationVersion applVers : appl.getVersions()) { applVers.setApplication(appl); appl.setMaxVersion(applVers.getNumber()); } } catch (final IOException e) { if (e.getCause() instanceof InstallationException) { throw (InstallationException) e.getCause(); } else { throw new InstallationException("Could not open / read version file '" + _versionUrl + "'"); } //CHECKSTYLE:OFF } catch (final Exception e) { //CHECKSTYLE:ON throw new InstallationException("Error while parsing file '" + _versionUrl + "'", e); } return appl; } /** * Returns the application definition read from a source directory. * * @param _versionFile version file which defines the application * @param _classpathElements class path elements (required to compile) * @param _eFapsDir root directory with the XML installation * files * @param _outputDir directory used as target for generated code * @param _includes list of includes; if <code>null</code> * {@link #DEFAULT_INCLUDES} are used * @param _excludes list of excludes; if <code>null</code> * {@link #DEFAULT_EXCLUDES} are used * @param _file2typeMapping mapping of file extension to type; if * <code>null</code> {@link #DEFAULT_TYPE_MAPPING} is used * @return application instance with all version information * @throws InstallationException if version file could not be read or opened */ public static Application getApplicationFromSource(final File _versionFile, final List<String> _classpathElements, final File _eFapsDir, final File _outputDir, final List<String> _includes, final List<String> _excludes, final Map<String, String> _file2typeMapping) throws InstallationException { final Map<String, String> file2typeMapping = _file2typeMapping == null ? Application.DEFAULT_TYPE_MAPPING : _file2typeMapping; final Application appl; try { appl = Application.getApplication(_versionFile.toURI().toURL(), _eFapsDir.toURI().toURL(), _classpathElements); for (final String fileName : Application.getFiles(_eFapsDir, _includes, _excludes)) { final String type = file2typeMapping.get(fileName.substring(fileName.lastIndexOf(".") + 1)); appl.install.addFile( new InstallFile().setType(type).setURL(new File(_eFapsDir, fileName).toURI().toURL())); } if (_outputDir.exists()) { for (final String fileName : Application.getFiles(_outputDir, _includes, _excludes)) { final String type = file2typeMapping.get(fileName.substring(fileName.lastIndexOf(".") + 1)); appl.install.addFile( new InstallFile().setType(type).setURL(new File(_outputDir, fileName).toURI().toURL())); } } } catch (final IOException e) { throw new InstallationException("Could not open / read version file " + "'" + _versionFile + "'", e); // CHECKSTYLE:OFF } catch (final Exception e) { // CHECKSTYLE:ON throw new InstallationException("Read version file '" + _versionFile + "' failed", e); } return appl; } /** * Uses the <code>_includes</code> and <code>_excludes</code> together with * the root directory <code>_eFapsDir</code> to get all related and matched * files. * * @param _eFapsDir root directory where the file are located * @param _includes defines includes; if not specified the default value is * <code>**/*.xml</code> * @param _excludes defines excludes; if not specified the default value is * <code>**/version.xml</code> * @return array of file names * @see #DEFAULT_INCLUDES * @see #DEFAULT_EXCLUDES */ protected static String[] getFiles(final File _eFapsDir, final List<String> _includes, final List<String> _excludes) { final DirectoryScanner ds = new DirectoryScanner(); final String[] included = _includes == null ? Application.DEFAULT_INCLUDES.toArray(new String[Application.DEFAULT_INCLUDES.size()]) : _includes.toArray(new String[_includes.size()]); final String[] excluded = _excludes == null ? Application.DEFAULT_EXCLUDES.toArray(new String[Application.DEFAULT_EXCLUDES.size()]) : _excludes.toArray(new String[_excludes.size()]); ds.setIncludes(included); ds.setExcludes(excluded); ds.setBasedir(_eFapsDir.toString()); ds.setCaseSensitive(true); ds.scan(); return ds.getIncludedFiles(); } /** * Method to get the applications from the class path. * * @param _application searched application in the class path * @param _classpath class path (list of the complete class path) * @return List of applications * @throws InstallationException if the install.xml file in the class path * could not be accessed */ public static Application getApplicationFromClassPath(final String _application, final List<String> _classpath) throws InstallationException { return Application.getApplicationsFromClassPath(_application, _classpath).get(_application); } /** * Method to get all applications from the class path. * * @param _application searched application in the class path * @param _classpath class path (list of the complete class path) * @return List of applications * @throws InstallationException if the install.xml file in the class path * could not be accessed */ public static Map<String, Application> getApplicationsFromClassPath(final String _application, final List<String> _classpath) throws InstallationException { final Map<String, Application> appls = new HashMap<String, Application>(); try { final ClassLoader parent = Application.class.getClassLoader(); final List<URL> urls = new ArrayList<>(); for (final String pathElement : _classpath) { urls.add(new File(pathElement).toURI().toURL()); } final URLClassLoader cl = URLClassLoader.newInstance(urls.toArray(new URL[urls.size()]), parent); // get install application (read from all install xml files) final Enumeration<URL> urlEnum = cl.getResources("META-INF/efaps/install.xml"); while (urlEnum.hasMoreElements()) { // TODO: why class path? final URL url = urlEnum.nextElement(); final Application appl = Application.getApplication(url, new URL(url, "../../../"), _classpath); appls.put(appl.getApplication(), appl); } } catch (final IOException e) { throw new InstallationException("Could not access the install.xml file " + "(in path META-INF/efaps/ path of each eFaps install jar).", e); } return appls; } /** * Returns the application read from given JAR file <code>_jarFile</code>. * * @param _jarFile JAR file with the application to install * @param _classpath class path (required to compile) * @return application instance * @throws InstallationException if application could not be fetched from * the JAR file or the version XML file could not be parsed */ public static Application getApplicationFromJarFile(final File _jarFile, final List<String> _classpath) throws InstallationException { try { final URL url = new URL("jar", null, 0, _jarFile.toURI().toURL().toString() + "!/"); final URL url2 = new URL(url, "/META-INF/efaps/install.xml"); return Application.getApplication(url2, new URL(url2, "../../../"), _classpath); } catch (final IOException e) { throw new InstallationException("URL could not be parsed", e); } } /** * Compiles the ESJP's and all Cascade Styles Sheets within eFaps. * * @param _userName name of logged in user for which the compile is done * (could be also <code>null</code>) * @param _classpath class path elements * @param _addRuntimeClassPath must the classpath from the runtime be added * to the classpath also * @throws InstallationException if reload cache of compile failed * @see #compileAll(String) */ public static void compileAll(final String _userName, final List<String> _classpath, final boolean _addRuntimeClassPath) throws InstallationException { new Application((URL) null, _classpath).compileAll(_userName, _addRuntimeClassPath); } /** * Compiles the ESJP's and all Cascade Styles Sheets within eFaps. * * @param _userName name of logged in user for which the compile is done * (could be also <code>null</code>) * @param _addRuntimeClassPath must the classpath from the runtime be added * to the classpath also * @throws InstallationException if reload cache of compile failed */ public void compileAll(final String _userName, final boolean _addRuntimeClassPath) throws InstallationException { if (Application.LOG.isInfoEnabled()) { Application.LOG.info("..Compiling"); } reloadCache(); try { Context.begin(_userName); try { new ESJPCompiler(getClassPathElements()).compile(null, _addRuntimeClassPath); } catch (final InstallationException e) { Application.LOG.error(" error during compilation of ESJP."); } try { AbstractStaticSourceCompiler.compileAll(this.classpathElements); } catch (final EFapsException e) { Application.LOG.error(" error during compilation of static sources."); } Context.commit(); } catch (final EFapsException e) { throw new InstallationException("Compile failed", e); } } /** * Installs current application including existing {@link #dependencies}. * * @param _userName name of logged in user * @param _password password of logged in user * @param _profiles set of profile to be applied * @throws InstallationException for all cases the installation failed * @see #install(String, String, boolean) */ public void install(final String _userName, final String _password, final Set<Profile> _profiles) throws InstallationException { this.install(_userName, _password, _profiles, null); } /** * Installs current application including existing {@link #dependencies}. * * @param _userName name of logged in user * @param _password password of logged in user * @param _profiles set of profile to be applied * @param _compile compile during the install/ if null the setting from the version.xml applies * @throws InstallationException for all cases the installation failed * @see #install(String, String, boolean) */ public void install(final String _userName, final String _password, final Set<Profile> _profiles, final Boolean _compile) throws InstallationException { this.install(_userName, _password, _profiles, _compile, true); } /** * For each version in {@link #versions} is tested, if it is already * installed. If not already installed, the version is installed. Only if * <code>_withDependency</code> is defined, also the {@link #dependencies} * are installed. * * @param _userName name of the installation user * @param _password password of the installation user * @param _profiles set of profile to be applied * @param _compile compile during the install/ if null the setting from the version.xml applies * @param _withDependency must the dependency also installed? * @throws InstallationException if installation failed */ protected void install(final String _userName, final String _password, final Set<Profile> _profiles, final Boolean _compile, final boolean _withDependency) throws InstallationException { // install dependency if required if (_withDependency) { for (final Dependency dependency : this.dependencies) { dependency.resolve(); final Application appl = Application.getApplicationFromJarFile(dependency.getJarFile(), this.classpathElements); appl.install(_userName, _password, dependency.getProfiles(), _compile, false); } } // reload cache (if possible) reloadCache(); // load latest installed versions final Map<String, Integer> latestVersions; try { Context.begin(); EFapsClassLoader.getOfflineInstance(getClass().getClassLoader()); latestVersions = this.install.getLatestVersions(); Context.rollback(); } catch (final EFapsException e) { throw new InstallationException("Could not get information about installed versions", e); } final Integer latestVersion = latestVersions.get(this.application); Application.LOG.info("Install application '" + this.application + "'"); for (final ApplicationVersion version : this.versions) { Application.LOG.info("Check version '{}'", version.getNumber()); if (_compile != null) { version.setCompile(_compile); } if (latestVersion != null && version.getNumber() < latestVersion) { if (Application.LOG.isInfoEnabled()) { Application.LOG.info("Version " + version.getNumber() + " already installed"); } } else { if (Application.LOG.isInfoEnabled()) { Application.LOG.info("Starting installation of version " + version.getNumber()); final String desc = version.getDescription(); if (!"".equals(desc)) { Application.LOG.info(desc); } } storeVersion(_userName, version.getNumber()); try { version.install(this.install, getLastVersion().getNumber(), _profiles, _userName, _password); //CHECKSTYLE:OFF } catch (final Exception e) { //CHECKSTYLE:ON throw new InstallationException("Installation failed", e); } if (Application.LOG.isInfoEnabled()) { Application.LOG.info("Finished installation of version " + version.getNumber()); } } } // reload cache (if possible) reloadCache(); } /** * Updates the last installed version. * * @param _userName name of logged in user * @param _password password of logged in user * @param _profiles Profiles to be applied * @throws Exception on error */ public void updateLastVersion(final String _userName, final String _password, final Set<Profile> _profiles) throws Exception { // reload cache (if possible) reloadCache(); // load installed versions Context.begin(); EFapsClassLoader.getOfflineInstance(getClass().getClassLoader()); final Map<String, Integer> latestVersions = this.install.getLatestVersions(); Context.rollback(); final long latestVersion = latestVersions.get(this.application); final ApplicationVersion version = getLastVersion(); if (version.getNumber() == latestVersion) { Application.LOG.info("Update version '{}' of application '{}' ", version.getNumber(), this.application); version.install(this.install, version.getNumber(), _profiles, _userName, _password); Application.LOG.info("Finished update of version '{}'", version.getNumber()); } else { Application.LOG.error("Version {}' of application '{}' not installed and could not updated!", version.getNumber(), this.application); } } /** * Store for this application that the version is already installed. If data * model in the local type cache is not loaded (because, e.g., it is a new * kernel install), the version numbers are cached.<br/> * The first time, the version type could be get from the type cache, all * cached versions are stored in eFaps. * * @param _userName logged in user name * @param _version version id to store * @throws InstallationException if version could not be stored */ protected void storeVersion(final String _userName, final Long _version) throws InstallationException { try { Context.begin(); if (Context.getDbType().existsView(Context.getThreadContext().getConnection(), "V_ADMINTYPE") && CIAdminCommon.ApplicationVersion.getType() != null && CIAdminCommon.Application.getType() != null && CIAdminCommon.Application.getType().getAttributes().size() > 4) { Context.commit(); Context.begin(_userName); // store cached versions for (final Long version : this.notStoredVersions) { final QueryBuilder appQueryBldr = new QueryBuilder(CIAdminCommon.Application); appQueryBldr.addWhereAttrEqValue(CIAdminCommon.Application.Name, this.application); final InstanceQuery appQuery = appQueryBldr.getQuery(); appQuery.execute(); Instance appInst; if (appQuery.next()) { appInst = appQuery.getCurrentValue(); } else { final Insert insert = new Insert(CIAdminCommon.Application); insert.add(CIAdminCommon.Application.Name, this.application); insert.execute(); appInst = insert.getInstance(); } final Insert insert = new Insert(CIAdminCommon.ApplicationVersion); insert.add(CIAdminCommon.ApplicationVersion.ApplicationLink, appInst); insert.add(CIAdminCommon.ApplicationVersion.Revision, version); insert.execute(); } this.notStoredVersions.clear(); final QueryBuilder appQueryBldr = new QueryBuilder(CIAdminCommon.Application); appQueryBldr.addWhereAttrEqValue(CIAdminCommon.Application.Name, this.application); final InstanceQuery appQuery = appQueryBldr.getQuery(); appQuery.execute(); Instance appInst; if (appQuery.next()) { appInst = appQuery.getCurrentValue(); } else { final Insert insert = new Insert(CIAdminCommon.Application); insert.add(CIAdminCommon.Application.Name, this.application); insert.execute(); appInst = insert.getInstance(); } final QueryBuilder queryBldr = new QueryBuilder(CIAdminCommon.ApplicationVersion); queryBldr.addWhereAttrEqValue(CIAdminCommon.ApplicationVersion.ApplicationLink, appInst); queryBldr.addWhereAttrEqValue(CIAdminCommon.ApplicationVersion.Revision, _version); final InstanceQuery query = queryBldr.getQuery(); query.execute(); if (!query.next()) { // store current version final Insert insert = new Insert(CIAdminCommon.ApplicationVersion); insert.add(CIAdminCommon.ApplicationVersion.ApplicationLink, appInst); insert.add(CIAdminCommon.ApplicationVersion.Revision, _version); insert.execute(); } } else { // if version could not be stored, cache the version information this.notStoredVersions.add(_version); } Context.commit(); } catch (final EFapsException e) { throw new InstallationException("Update of the version information failed", e); } catch (final SQLException e) { throw new InstallationException("Update of the version information failed", e); } } /** * * @param _dependency dependency */ @SetNext public void addDependency(final Dependency _dependency) { this.dependencies.add(_dependency); } /** * Reloads the eFaps cache. * * @throws InstallationException if reload of the cache failed */ protected void reloadCache() throws InstallationException { try { Context.begin(); if (RunLevel.isInitialisable()) { RunLevel.init("shell"); RunLevel.execute(); } Context.rollback(); } catch (final EFapsException e) { throw new InstallationException("Reload cache failed", e); } } /** * Adds a n ew application version to this application which should be * installed. * * @param _version new application version to add */ @SetNext public void addVersion(final ApplicationVersion _version) { this.versions.add(_version); } /** * Returns the last application version which must be installed. * * @return last application version to install */ public ApplicationVersion getLastVersion() { return (ApplicationVersion) this.versions.toArray()[this.versions.size() - 1]; } /** * Setter method for instance variable {@link #application}. * * @param _application value for instance variable {@link #application} */ public void setApplication(final String _application) { this.application = _application; } /** * Searches for the given file name (parameter _classPathFile) in the class * path and adds them as URL to the list of XML installation / update / * definition files ({@link #install}). * * @param _classPathFile file name from the class path to add * @param _type type of the file to be added * @param _revision revision of the file to be added * @param _date date of the file to be added * @throws MalformedURLException on error with the URL * @see #addURL(URL, String) */ @CallMethod(pattern = "install/files/file") public void addClassPathFile( @CallParam(pattern = "install/files/file", attributeName = "name") final String _classPathFile, @CallParam(pattern = "install/files/file", attributeName = "type") final String _type, @CallParam(pattern = "install/files/file", attributeName = "revision") final String _revision, @CallParam(pattern = "install/files/file", attributeName = "date") final String _date) throws MalformedURLException { this.tmpElements.add(new InstallFile().setName(_classPathFile).setType(_type).setRevision(_revision) .setDate(_date != null ? new DateTime(_date) : new DateTime())); } /** * Getter method for the instance variable {@link #install}. * * @return value of instance variable {@link #install} */ public Install getInstall() { return this.install; } /** * Getter method for the instance variable {@link #dependencies}. * * @return value of instance variable {@link #dependencies} */ public List<Dependency> getDependencies() { return this.dependencies; } /** * This is the getter method for instance variable {@link #application}. * * @return value of instance variable {@link #application} * @see #application */ public String getApplication() { return this.application; } /** * Returns all class path elements required to compile. * * @return class path elements * @see #classpathElements */ public List<String> getClassPathElements() { return this.classpathElements; } /** * Returns the root URL where the source is located. For local sources it is * an URL to a directory, for a Jar file it is the URL to the Jar file. * * @return value of instance variable {@link #rootUrl} */ public URL getRootUrl() { return this.rootUrl; } /** * This is the getter method for instance variable {@link #versions}. * * @return value of instance variable {@link #versions} * @see #versions */ public Set<ApplicationVersion> getVersions() { return this.versions; } /** * This is the setter method for the instance variable {@link #maxVersion}. * * @param _maxVersion the maxVersion to set */ public void setMaxVersion(final Long _maxVersion) { this.maxVersion = _maxVersion; } /** * This is the getter method for the instance variable {@link #maxVersion}. * * @return value of instance variable {@link #maxVersion} */ public Long getMaxVersion() { return this.maxVersion; } /** * Setter method for instance variable {@link #rootPackageName}. * * @param _rootPackageName value for instance variable * {@link #rootPackageName} */ public void setRootPackageName(final String _rootPackageName) { this.rootPackageName = _rootPackageName; } /** * Getter method for instance variable {@link #rootPackageName}. * * @return value of instance variable {@link #rootPackageName} */ public String getRootPackageName() { return this.rootPackageName; } /** * Returns a string representation with values of all instance variables. * * @return string representation of this Application */ @Override public String toString() { return new ToStringBuilder(this).append("application", this.application) .append("dependencies", this.dependencies).append("versions", this.versions) .append("install", this.install).toString(); } }