/*
 * 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.
 */
package org.apache.sling.jcr.repoinit.impl;

import java.io.StringReader;
import java.util.Arrays;
import java.util.List;

import javax.jcr.Session;

import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.api.SlingRepositoryInitializer;
import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
import org.apache.sling.repoinit.parser.RepoInitParser;
import org.apache.sling.repoinit.parser.operations.Operation;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** SlingRepositoryInitializer that executes repoinit statements read
 *  from a configurable URL.
 */
@Designate(ocd = RepositoryInitializer.Config.class)
@Component(service = SlingRepositoryInitializer.class,
    property = {
            Constants.SERVICE_VENDOR + "=The Apache Software Foundation",
            // SlingRepositoryInitializers are executed in ascending
            // order of their service ranking
            Constants.SERVICE_RANKING + ":Integer=100"
    })
public class RepositoryInitializer implements SlingRepositoryInitializer {

    @ObjectClassDefinition(name = "Apache Sling Repository Initializer",
        description="Initializes the JCR content repository using repoinit statements")
    public @interface Config {

        @AttributeDefinition(name="Repoinit references",
            description=
                 "References to the source text that provides repoinit statements."
                + " format is either model@repoinit:<provisioning model URL> or raw:<raw URL>")
        String[] references() default {};
    }
    private final Logger log = LoggerFactory.getLogger(getClass());


    @Reference
    private RepoInitParser parser;

    @Reference
    private JcrRepoInitOpsProcessor processor;

    private Config config;

    @Activate
    public void activate(Config config) {
        this.config = config;
        log.debug("Activated: {}", this.toString());
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + ", references=" + Arrays.toString(config.references());
    }

    @Override
    public void processRepository(SlingRepository repo) throws Exception {
        // loginAdministrative is ok here, definitely an admin operation
        final Session s = repo.loginAdministrative(null);
        try {
            final RepoinitTextProvider p = new RepoinitTextProvider();
            for(String reference : config.references()) {
                final String repoinitText = p.getRepoinitText(reference);
                final List<Operation> ops = parser.parse(new StringReader(repoinitText));
                log.info("Executing {} repoinit operations", ops.size());
                processor.apply(s, ops);
                s.save();
            }
        } finally {
            s.logout();
        }
    }
}

@@ -3347,16 +3347,99 @@
 ption %7B%0A
+        if ( config.references() != null && config.references().length %3E 0 ) %7B%0A    
         
@@ -3507,24 +3507,28 @@
 ion%0A        
+    
 final Sessio
@@ -3565,16 +3565,20 @@
 (null);%0A
+    
         
@@ -3591,24 +3591,28 @@
             
+    
 final Repoin
@@ -3670,16 +3670,20 @@
         
+    
 for(Stri
@@ -3732,24 +3732,28 @@
             
+ 
+   
 final String
@@ -3798,16 +3798,20 @@
 rence);%0A
+    
         
@@ -3904,24 +3904,28 @@
             
+  
+  
 log.info(%22Ex
@@ -3986,16 +3986,20 @@
         
+    
 processo
@@ -4031,16 +4031,20 @@
         
+   
+ 
 s.save()
@@ -4053,26 +4053,34 @@
             
-%7D%0A
+    %7D%0A    
         %7D fi
@@ -4099,16 +4099,20 @@
         
+    
 s.logout
@@ -4111,24 +4111,38 @@
 s.logout();%0A
+            %7D%0A
         %7D%0A  

Fix NPE in processing