/*
 *  Copyright 2013
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may use this file in compliance with the Apache License, Version 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 net.sf.plugfy.verifier;

import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import net.sf.plugfy.verifier.violations.SpringViolation;

import org.apache.bcel.util.Repository;


/**
 * context of a verification run
 *
 * @author hendrik
 */
public class VerificationContext {

    private final VerificationResult result = new VerificationResult();

    private Repository repository;

    private ClassLoader classLoader;

    private final URL underVerification;

    /** Map from bean identifier to bean class */
    private final Map<String, String> beanDefinitions = new HashMap<String, String>();

    /** Map from bean alias to bean identifier */
    private final Map<String, String> beanAliases = new HashMap<String, String>();

    private final Set<SpringViolation> requiredBeanIds = new HashSet<SpringViolation>();

    /**
     * VerificationContext
     *
     * @param repository bcel repository
     * @param classLoader class loader
     * @param url the resource under verification
     */
    public VerificationContext(final Repository repository, final ClassLoader classLoader, final URL url) {
        this.repository = repository;
        this.classLoader = classLoader;
        this.underVerification = url;
    }

    /**
     * @return the result
     */
    public VerificationResult getResult() {
        return this.result;
    }

    /**
     * @return the repository
     */
    public Repository getRepository() {
        return this.repository;
    }

    /**
     * @param repository Repository
     */
    public void setRepository(final Repository repository) {
        this.repository = repository;
    }

    /**
     * @return recursive?
     */
    public boolean isRecursive() {
        return false;
    }

    /**
     * @return the classLoader
     */
    public ClassLoader getClassLoader() {
        return this.classLoader;
    }

    /**
     * @param classLoader the classLoader to set
     */
    public void setClassLoader(final ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public String toString() {
        return "VerificationContext [verified=" + this.underVerification.toExternalForm() + ", result=" + this.result + ", missingBeanIds="+this.requiredBeanIds+"]";
    }

    /**
     * @return the url of the resource, which is under verification
     */
    public URL getUnderVerification() {
        return this.underVerification;
    }

    /**
     * Mark a bean as required, which has not yet been found
     * 
     * @param possibleViolation
     */
    public void requireBean(final SpringViolation possibleViolation) {
        if(!this.beanDefinitions.containsKey(possibleViolation.getBeanId())) {
            if (!this.beanAliases.containsKey(possibleViolation.getBeanId())) {
                this.requiredBeanIds.add(possibleViolation);
            }
        }
    }

    /**
     * Register bean definitions
     * 
     * @param beanId
     * @param beanClass
     */
    public void registerBean(final String beanId, final String beanClass) {
        final Iterator<SpringViolation> i = this.requiredBeanIds.iterator();
        while(i.hasNext()) {
            final SpringViolation v = i.next();
            if(v.getBeanId().equals(beanId)) {
                i.remove();
            }
        }
        this.beanDefinitions.put(beanId, beanClass);
    }

    /**
     * @param alias
     * @param beanToAlias
     */
    public void registerAlias(final String alias, final String beanToAlias) {
        this.beanAliases.put(alias, beanToAlias);
    }

}

@@ -1800,21 +1800,16 @@
         
-this.
 underVer
@@ -1824,32 +1824,510 @@
 n = url;%0A    %7D%0A%0A
+    /**%0A     * VerificationContext%0A     *%0A     * @param repository bcel repository%0A     * @param classLoader class loader%0A     * @param url the resource under verification%0A     * @param beanDefinitions present beans%0A     */%0A    public VerificationContext(final Repository repository, final ClassLoader classLoader, final URL url, final Map%3CString, String%3E beanDefinitions) %7B%0A        this(repository,classLoader,url);%0A        this.beanDefinitions.putAll(beanDefinitions);%0A    %7D%0A%0A
     /**%0A     * @
@@ -2411,21 +2411,16 @@
  return 
-this.
 result;%0A
@@ -2527,21 +2527,16 @@
  return 
-this.
 reposito
@@ -2914,21 +2914,16 @@
  return 
-this.
 classLoa
@@ -3205,21 +3205,16 @@
 ied=%22 + 
-this.
 underVer
@@ -3256,21 +3256,16 @@
 ult=%22 + 
-this.
 result +
@@ -3285,21 +3285,16 @@
 anIds=%22+
-this.
 required
@@ -3452,21 +3452,16 @@
  return 
-this.
 underVer
@@ -3678,21 +3678,16 @@
     if(!
-this.
 beanDefi
@@ -3757,21 +3757,16 @@
    if (!
-this.
 beanAlia
@@ -3831,21 +3831,16 @@
         
-this.
 required
@@ -4124,21 +4124,16 @@
 on%3E i = 
-this.
 required
@@ -4328,37 +4328,32 @@
       %7D%0A        
-this.
 beanDefinitions.
@@ -4519,32 +4519,32 @@
 nToAlias) %7B%0A
+
         
 this.beanAli
@@ -4527,29 +4527,24 @@
 ) %7B%0A        
-this.
 beanAliases.

add possibility to add an existing spring context