<?xml version="1.0"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.
-->

<model xmlns="http://modello.codehaus.org/MODELLO/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.0.0 http://modello.codehaus.org/xsd/modello-1.0.0.xsd"
  xml.namespace="http://maven.apache.org/PLUGIN_REGISTRY/${version}"
  xml.schemaLocation="http://maven.apache.org/xsd/plugin-registry-${version}.xsd">
  <id>plugin-registry</id>
  <name>PluginRegistry</name>
  <description><![CDATA[
    Contains plugin version information related to which version of a particular plugin to use,
    when and how to update plugins, and which versions of a plugin have already been declined for
    update.
  ]]></description>
  <defaults>
    <default>
      <key>package</key>
      <value>org.apache.maven.plugin.registry</value>
    </default>
  </defaults>
  <classes>
    <class>
      <name>TrackableBase</name>
      <version>1.0.0</version>
      <description>common base class that contains code to track the source for this instance (USER|GLOBAL)</description>
      <codeSegments>
        <codeSegment>
          <version>1.0.0</version>
          <code><![CDATA[
    public static final String USER_LEVEL = "user-level";
    public static final String GLOBAL_LEVEL = "global-level";

    private String sourceLevel = USER_LEVEL;
    private boolean sourceLevelSet = false;

    public void setSourceLevel( String sourceLevel )
    {
        if ( sourceLevelSet )
        {
            throw new IllegalStateException( "Cannot reset sourceLevel attribute; it is already set to: " + sourceLevel );
        }
        else if ( !( USER_LEVEL.equals( sourceLevel ) || GLOBAL_LEVEL.equals( sourceLevel ) ) )
        {
            throw new IllegalArgumentException( "sourceLevel must be one of: {" + USER_LEVEL + "," + GLOBAL_LEVEL + "}" );
        }
        else
        {
            this.sourceLevel = sourceLevel;
            this.sourceLevelSet = true;
        }
    }

    public String getSourceLevel()
    {
        return sourceLevel;
    }
          ]]></code>
        </codeSegment>
      </codeSegments>
    </class>
    <class rootElement="true" xml.tagName="pluginRegistry">
      <name>PluginRegistry</name>
      <version>1.0.0</version>
      <superClass>TrackableBase</superClass>
      <description>Root element of the plugin registry file.</description>
      <fields>
        <field>
          <name>updateInterval</name>
          <version>1.0.0</version>
          <type>String</type>
          <defaultValue>never</defaultValue>
          <description><![CDATA[
            Specifies how often to check for plugin updates. Valid values are: never, always, interval:XXX.
            For the interval specification, XXX denotes a terse interval specification, such as 4h.
            Where h=hours, m=minutes, d=days, w=weeks. The interval period should be specified in descending
            order of granularity, like this: '[n]w [n]d [n]h [n]m'. Any omitted level of granularity will be
            assumed to be a zero value.
          ]]></description>
        </field>
        <field>
          <name>autoUpdate</name>
          <version>1.0.0</version>
          <type>String</type>
          <description>Specifies whether the user should be prompted to update plugins.</description>
        </field>
        <field>
          <name>checkLatest</name>
          <version>1.0.0</version>
          <type>String</type>
          <description>Whether to resolve plugin versions using LATEST metadata.</description>
        </field>
        <field>
          <name>plugins</name>
          <version>1.0.0</version>
          <description>Specified plugin update policy information.</description>
          <association>
            <type>Plugin</type>
            <multiplicity>*</multiplicity>
          </association>
        </field>
      </fields>
      <codeSegments>
        <codeSegment>
          <version>1.0.0</version>
          <code><![CDATA[
    private java.util.Map pluginsByKey;

    public java.util.Map getPluginsByKey()
    {
        if ( pluginsByKey == null )
        {
            pluginsByKey = new java.util.HashMap();

            for ( java.util.Iterator it = getPlugins().iterator(); it.hasNext(); )
            {
                Plugin plugin = (Plugin) it.next();

                pluginsByKey.put( plugin.getKey(), plugin );
            }
        }

        return pluginsByKey;
    }

    public void flushPluginsByKey()
    {
        this.pluginsByKey = null;
    }

    private RuntimeInfo runtimeInfo;

    public void setRuntimeInfo( RuntimeInfo runtimeInfo )
    {
        this.runtimeInfo = runtimeInfo;
    }

    public RuntimeInfo getRuntimeInfo()
    {
        return runtimeInfo;
    }
        ]]></code>
        </codeSegment>
      </codeSegments>
    </class>
    <class>
      <name>Plugin</name>
      <version>1.0.0</version>
      <superClass>TrackableBase</superClass>
      <description>Policy for updating a single plugin.</description>
      <fields>
        <field>
          <name>groupId</name>
          <version>1.0.0</version>
          <required>true</required>
          <type>String</type>
        </field>
        <field>
          <name>artifactId</name>
          <version>1.0.0</version>
          <required>true</required>
          <type>String</type>
        </field>
        <field>
          <name>lastChecked</name>
          <version>1.0.0</version>
          <type>String</type>
          <description>[format: yyyy-MM-dd.HH:mm:ss Z] Specifies the date/time at which this plugin was last checked.</description>
        </field>
        <field>
          <name>useVersion</name>
          <version>1.0.0</version>
          <type>String</type>
          <description>The current version of this plugin, to be used until the appropriate update actions happen.</description>
        </field>
        <field>
          <name>rejectedVersions</name>
          <version>1.0.0</version>
          <description>The list of versions for this plugin that the user declined to "install"</description>
          <association>
            <type>String</type>
            <multiplicity>*</multiplicity>
          </association>
        </field>
      </fields>
      <codeSegments>
        <codeSegment>
          <version>1.0.0</version>
          <code><![CDATA[
    public static final String LAST_CHECKED_DATE_FORMAT = "yyyy-MM-dd.HH:mm:ss Z";

    public String getKey()
    {
        return getGroupId() + ":" + getArtifactId();
    }
          ]]></code>
        </codeSegment>
      </codeSegments>
    </class>
  </classes>
</model>
