001package org.apache.maven.toolchain;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.HashMap;
023import java.util.Iterator;
024import java.util.Map;
025import java.util.Properties;
026
027import org.apache.maven.toolchain.model.ToolchainModel;
028import org.codehaus.plexus.logging.Logger;
029
030/**
031 * Default abstract toolchain implementation, to be used as base class for any toolchain implementation
032 * to avoid rewriting usual code.
033 *
034 * @author mkleint
035 * @since 2.0.9
036 */
037public abstract class DefaultToolchain // should have been AbstractToolchain...
038    implements Toolchain, ToolchainPrivate
039{
040
041    private String type;
042
043    private Map<String, RequirementMatcher> provides = new HashMap<>();
044
045    public static final String KEY_TYPE = "type"; //NOI18N
046
047    private ToolchainModel model;
048
049    private Logger logger;
050
051    /**
052     * 
053     * @param model the model, must not be {@code null}
054     * @param logger the logger, must not be {@code null}
055     */
056    protected DefaultToolchain( ToolchainModel model, Logger logger )
057    {
058        this.model = model;
059
060        this.logger = logger;
061    }
062
063    /**
064     * 
065     * @param model the model, must not be {@code null}
066     * @param type the type
067     * @param logger the logger, must not be {@code null}
068     */
069    protected DefaultToolchain( ToolchainModel model, String type, Logger logger )
070    {
071        this( model, logger );
072        this.type = type;
073    }
074
075    @Override
076    public final String getType()
077    {
078        return type != null ? type : model.getType();
079    }
080
081    @Override
082    public final ToolchainModel getModel()
083    {
084        return model;
085    }
086
087    public final void addProvideToken( String type, RequirementMatcher matcher )
088    {
089        provides.put( type, matcher );
090    }
091
092    @Override
093    public boolean matchesRequirements( Map<String, String> requirements )
094    {
095        for ( Map.Entry<String, String> requirement : requirements.entrySet() )
096        {
097            String key = requirement.getKey();
098
099            RequirementMatcher matcher = provides.get( key );
100
101            if ( matcher == null )
102            {
103                getLog().debug( "Toolchain " + this + " is missing required property: " + key );
104                return false;
105            }
106            if ( !matcher.matches( requirement.getValue() ) )
107            {
108                getLog().debug( "Toolchain " + this + " doesn't match required property: " + key );
109                return false;
110            }
111        }
112        return true;
113    }
114
115    protected Logger getLog()
116    {
117        return logger;
118    }
119
120    @Override
121    public boolean equals( Object obj )
122    {
123        if ( obj == null )
124        {
125            return false;
126        }
127
128        if ( this == obj )
129        {
130            return true;
131        }
132
133        if ( !( obj instanceof DefaultToolchain ) )
134        {
135            return false;
136        }
137
138        DefaultToolchain other = (DefaultToolchain) obj;
139
140        if ( type == null ? other.type != null : !type.equals( other.type ) )
141        {
142            return false;
143        }
144
145        Properties thisProvides = this.getModel().getProvides();
146        Properties otherProvides = other.getModel().getProvides();
147
148        if ( thisProvides == null ? otherProvides != null : !thisProvides.equals( otherProvides ) )
149        {
150            return false;
151        }
152
153        return true;
154    }
155
156    @Override
157    public int hashCode()
158    {
159        int hashCode = ( type == null ) ? 0 : type.hashCode();
160
161        if ( this.getModel().getProvides() != null )
162        {
163            hashCode = 31 * hashCode + this.getModel().getProvides().hashCode();
164        }
165        return hashCode;
166    }
167    
168    @Override
169    public String toString()
170    {
171        StringBuilder builder = new StringBuilder();
172        builder.append( "type:" ).append( getType() );
173        builder.append( '{' );
174
175        Iterator<Map.Entry<String, RequirementMatcher>> providesIter = provides.entrySet().iterator();
176        while ( providesIter.hasNext() )
177        {
178            Map.Entry<String, RequirementMatcher> provideEntry = providesIter.next();
179            builder.append( provideEntry.getKey() ).append( " = " ).append( provideEntry.getValue() );
180            if ( providesIter.hasNext() )
181            {
182                builder.append( ';' );
183            }
184        }
185        
186        builder.append( '}' );
187        
188        return builder.toString();
189    }
190}