/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.component;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.junit.Assert;
import org.junit.Test;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Role;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;

/**
 * Verifies that XWiki components using JSR330 annotation can be used with Guice, thus demonstrating that we're kind of
 * spec compliant (even if we do not implement the whole JSR330 specification).
 * 
 * @version $Id$
 * @since 3.1M1
 */
public class GuiceCompatibilityTest
{
    @Role
    public interface FieldRole
    {
    }

    @Component
    @Singleton
    public static class FieldRoleImpl implements FieldRole
    {
    }

    @Role
    public interface RoleClass
    {
    }

    @Component
    @Named("whatever")
    public static class RoleImpl implements RoleClass
    {
        @Inject
        @Named("name")
        private FieldRole fieldRole;

        public FieldRole getFieldRole()
        {
            return this.fieldRole;
        }
    }

    public class TestModule extends AbstractModule
    {
        @Override
        protected void configure()
        {
            bind(FieldRole.class).annotatedWith(Names.named("name")).to(FieldRoleImpl.class);
        }
    }

    @Test
    public void testGuice()
    {
        Injector injector = Guice.createInjector(new TestModule());

        RoleImpl impl1 = injector.getInstance(RoleImpl.class);
        Assert.assertEquals(FieldRoleImpl.class.getName(), impl1.getFieldRole().getClass().getName());

        // Test that FieldRole impl is a singleton
        RoleImpl impl2 = injector.getInstance(RoleImpl.class);
        Assert.assertSame(impl1.getFieldRole(), impl2.getFieldRole());
    }
}

@@ -972,16 +972,46 @@
 .Named;%0A
+import javax.inject.Provider;%0A
 import j
@@ -1670,24 +1670,43 @@
  @Component%0A
+    @Named(%22name%22)%0A
     @Singlet
@@ -1737,32 +1737,121 @@
 ss FieldRoleImpl
+1 implements FieldRole%0A    %7B%0A    %7D%0A%0A    @Component%0A    public static class FieldRoleImpl2
  implements Fiel
@@ -1915,32 +1915,230 @@
 ss%0A    %7B%0A    %7D%0A%0A
+    @Component%0A    public static class ProviderImpl implements Provider%3CFieldRole%3E%0A    %7B%0A        @Override public FieldRole get()%0A        %7B%0A            return new FieldRoleImpl2();%0A        %7D%0A    %7D%0A%0A
     @Component%0A 
@@ -2293,16 +2293,89 @@
 ieldRole
+1;%0A%0A        @Inject%0A        private Provider%3CFieldRole%3E fieldRoleProvider
 ;%0A%0A     
@@ -2406,16 +2406,17 @@
 ieldRole
+1
 ()%0A     
@@ -2453,16 +2453,128 @@
 ieldRole
+1;%0A        %7D%0A%0A        public FieldRole getFieldRole2()%0A        %7B%0A            return this.fieldRoleProvider.get()
 ;%0A      
@@ -2781,32 +2781,99 @@
 to(FieldRoleImpl
+1.class);%0A            bind(FieldRole.class).toProvider(ProviderImpl
 .class);%0A       
@@ -3095,24 +3095,25 @@
 ieldRoleImpl
+1
 .class.getNa
@@ -3136,16 +3136,122 @@
 ieldRole
+1().getClass().getName());%0A        Assert.assertEquals(FieldRoleImpl2.class.getName(), impl1.getFieldRole2
 ().getCl
@@ -3427,16 +3427,17 @@
 ieldRole
+1
 (), impl
@@ -3450,16 +3450,17 @@
 ieldRole
+1
 ());%0A   

Add test to prove that the way XWiki uses Providers also works fine when an XWiki Component is used in Guice.