Package org.apache.sling.jcr.compiler.impl

Source Code of org.apache.sling.jcr.compiler.impl.JcrJavaCompilerImpl$Source

/*
* 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.compiler.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.compiler.CompilationResult;
import org.apache.sling.commons.compiler.CompilationUnit;
import org.apache.sling.commons.compiler.CompilerMessage;
import org.apache.sling.commons.compiler.JavaCompiler;
import org.apache.sling.commons.compiler.Options;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.compiler.JcrJavaCompiler;

/**
* <code>JcrJavaCompilerImpl</code> ...
*
*/
@Component
@Service(value=JcrJavaCompiler.class)
public class JcrJavaCompilerImpl implements JcrJavaCompiler {

    @Reference
    protected JavaCompiler compiler;

    @Reference
    protected SlingRepository repository;

    /**
     * @see org.apache.sling.jcr.compiler.JcrJavaCompiler#compile(java.lang.String[], java.lang.String, org.apache.sling.commons.compiler.Options)
     */
    public CompilationResult compile(final String[] srcFiles,
                                     final String outputDir,
                                     final Options compilerOptions)
    throws Exception {
        return compile(srcFiles, compilerOptions);
    }

    /**
     * @see org.apache.sling.jcr.compiler.JcrJavaCompiler#compile(java.lang.String[], org.apache.sling.commons.compiler.Options)
     */
    public CompilationResult compile(final String[] srcFiles, final Options compilerOptions)
    throws Exception {
        // make sure we have options
        final Options options = (compilerOptions == null ? new Options() : new Options(compilerOptions));
        // open session
        Session session = null;
        try {
            session = this.repository.loginAdministrative(null);

            // create compilation units
            CompilationUnit[] units = new CompilationUnit[srcFiles.length];
            for (int i = 0; i < units.length; i++) {
                units[i] = createCompileUnit(srcFiles[i], session);
            }

            // and compile
            return mapResult(compiler.compile(units, options), srcFiles, units);
        } finally {
            if ( session != null ) {
                session.logout();
            }
        }
    }

    /**
     * Map the source information of the errors
     */
    private CompilationResult mapResult(final CompilationResult result,
            final String[] srcFiles,
            final CompilationUnit[] units) {
        if ( result == null || (result.getErrors() == null && result.getWarnings() == null ) ) {
            return result;
        }

        final Map<String, String> mapping = new HashMap<String, String>();
        for(int i=0;i<srcFiles.length;i++) {
            mapping.put(units[i].getMainClassName() + ".java", srcFiles[i]);
        }
        return new CompilationResult() {

            private List<CompilerMessage> mapMessages(final List<CompilerMessage> msgs) {
                if ( msgs == null || msgs.size() == 0 ) {
                    return msgs;
                }
                final List<CompilerMessage> newMsgs = new ArrayList<CompilerMessage>();
                for(final CompilerMessage msg : msgs) {
                    final String mapped = mapping.get(msg.getFile());

                    newMsgs.add(new CompilerMessage(
                            mapped == null ? msg.getFile() : mapped,
                            msg.getLine(), msg.getColumn(), msg.getMessage()));
                }
                return newMsgs;
            }

            public Class<?> loadCompiledClass(String className)
                    throws ClassNotFoundException {
                return result.loadCompiledClass(className);
            }

            public List<CompilerMessage> getWarnings() {
                return mapMessages(result.getWarnings());
            }

            public List<CompilerMessage> getErrors() {
                return mapMessages(result.getErrors());
            }

            public boolean didCompile() {
                return result.didCompile();
            }
        };
    }

    //--------------------------------------------------------< misc. helpers >

    private CompilationUnit createCompileUnit(final String sourceFile, final Session session)
    throws RepositoryException, IOException {
        final Source source = readTextResource(sourceFile, session);
        final String packageName = extractPackageName(source.contents);

        return new CompilationUnit() {

            /**
             * @see org.apache.sling.commons.compiler.CompilationUnit#getMainClassName()
             */
            public String getMainClassName() {
                return packageName + '.' + this.getMainTypeName();
            }

            /**
             * @see org.apache.sling.commons.compiler.CompilationUnit#getSource()
             */
            public Reader getSource() throws IOException {
                return new StringReader(source.contents);
            }

            /**
             * @see org.apache.sling.commons.compiler.CompilationUnit#getLastModified()
             */
            public long getLastModified() {
                return source.lastModified;
            }

            private String getMainTypeName() {
                String className;
                int pos = sourceFile.lastIndexOf(".java");
                if (pos != -1) {
                    className = sourceFile.substring(0, pos).trim();
                } else {
                    className = sourceFile.trim();
                }
                pos = className.lastIndexOf('/');
                return (pos == -1) ? className : className.substring(pos + 1);
            }
        };
    }

    private String extractPackageName(final String contents) {
        BufferedReader reader = new BufferedReader(new StringReader(contents));
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                if (line.startsWith("package")) {
                    line = line.substring("package".length());
                    line = line.substring(0, line.lastIndexOf(';'));
                    return line.trim();
                }
            }
        } catch (IOException e) {
            // should never get here...
        }

        // no package declaration found
        return "";
    }

    private Source readTextResource(final String resourcePath, final Session session)
    throws RepositoryException, IOException {
        final Source source = new Source();
        final String relPropPath = resourcePath.substring(1) + "/jcr:content/jcr:data";
        final InputStream in = session.getRootNode().getProperty(relPropPath).getStream();
        final Reader reader = new InputStreamReader(in, "UTF-8");
        final StringWriter writer = new StringWriter();
        try {
            final char[] buffer = new char[2048];
            int read = 0;
            while ((read = reader.read(buffer)) > 0) {
                writer.write(buffer, 0, read);
            }
            writer.close();
            source.contents = writer.toString();
            final String lastModPath = resourcePath + "/jcr:content/jcr:lastModified";
            source.lastModified = session.itemExists(lastModPath) ? ((Property)session.getItem(lastModPath)).getLong() : -1;
            return source;
        } finally {
            try { reader.close(); } catch (IOException ignore) {}
        }
    }

    private static final class Source {
        public String contents;
        public long lastModified;
    }
}
TOP

Related Classes of org.apache.sling.jcr.compiler.impl.JcrJavaCompilerImpl$Source

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.