Package org.netbeans.gradle.project

Source Code of org.netbeans.gradle.project.ExtensionLoader$SerializableLookup$SerializedFormat

package org.netbeans.gradle.project;

import java.io.File;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jtrim.utils.ExceptionHelper;
import org.netbeans.api.project.Project;
import org.netbeans.gradle.model.util.CollectionUtils;
import org.netbeans.gradle.project.api.entry.GradleProjectExtension2;
import org.netbeans.gradle.project.api.entry.GradleProjectExtensionDef;
import org.netbeans.gradle.project.api.entry.ModelLoadResult;
import org.netbeans.gradle.project.api.entry.ParsedModel;
import org.netbeans.gradle.project.api.modelquery.GradleModelDefQuery1;
import org.netbeans.gradle.project.api.modelquery.GradleTarget;
import org.netbeans.gradle.project.model.GradleModelLoader;
import org.openide.modules.SpecificationVersion;
import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;

public final class ExtensionLoader {
    private static final Logger LOGGER = Logger.getLogger(ExtensionLoader.class.getName());
    private static final SpecificationVersion JAVA6_VERSION = new SpecificationVersion("1.6");

    private static Level levelFromException(Throwable exception) {
        if (exception instanceof RuntimeException) {
            return Level.WARNING;
        }
        else if (exception instanceof Error) {
            return Level.SEVERE;
        }
        else {
            return Level.INFO;
        }
    }

    /** @deprecated */
    @Deprecated
    @SuppressWarnings("UseSpecificCatch")
    private static NbGradleExtensionRef loadExtension(
            NbGradleProject project,
            org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery def) {

        org.netbeans.gradle.project.api.entry.GradleProjectExtension extension = null;

        try {
            extension = def.loadExtensionForProject(project);
            Objects.requireNonNull(extension, "def.loadExtensionForProject");

            File projectDir = project.getProjectDirectoryAsFile();
            GradleProjectExtensionDef<SerializableLookup> def2
                    = createWrappedDef(projectDir, def, extension);
            GradleProjectExtension2<SerializableLookup> extension2
                    = createWrappedProjectExtension(extension);
            return new NbGradleExtensionRef(def2, extension2);
        } catch (Throwable ex) {
            String name = extension != null
                    ? extension.getExtensionName()
                    : def.getClass().getName();

            LOGGER.log(levelFromException(ex),
                    "Failed to load extension: " + name + " for project " + project.getProjectDirectory(),
                    ex);
            return null;
        }
    }

    private static <ModelType> NbGradleExtensionRef loadExtension(
            NbGradleProject project,
            GradleProjectExtensionDef<ModelType> def) throws IOException {

        try {
            GradleProjectExtension2<ModelType> extension = def.createExtension(project);
            return new NbGradleExtensionRef(def, extension);
        } catch (Throwable ex) {
            LOGGER.log(levelFromException(ex),
                    "Failed to load extension: " + def.getName() + " for project " + project.getProjectDirectory(),
                    ex);
            return null;
        }
    }

    private static void tryAddExtension(
            Object sourceDef,
            NbGradleExtensionRef extension,
            List<NbGradleExtensionRef> result,
            Set<String> alreadyLoaded) {
        if (extension == null) {
            return;
        }

        if (alreadyLoaded.contains(extension.getName())) {
            LOGGER.log(Level.WARNING, "Extension has already been loaded with the same name: {0}. Ignoring implementation: {1}",
                    new Object[]{extension.getName(), sourceDef.getClass().getName()});
        }
        else {
            result.add(extension);
        }
    }

    @SuppressWarnings("unchecked")
    private static Class<GradleProjectExtensionDef<?>> defClass() {
        return (Class<GradleProjectExtensionDef<?>>)(Class<?>)GradleProjectExtensionDef.class;
    }

    @SuppressWarnings("deprecation")
    public static List<NbGradleExtensionRef> loadExtensions(NbGradleProject project) throws IOException {
        Lookup defaultLookup = Lookup.getDefault();

        Collection<? extends org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery> defs1
                = defaultLookup.lookupAll(org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery.class);

        Collection<? extends GradleProjectExtensionDef<?>> defs2
                = defaultLookup.lookupAll(defClass());

        int expectedExtensionCount = defs1.size() + defs2.size();
        List<NbGradleExtensionRef> result = new ArrayList<>(expectedExtensionCount);

        Set<String> alreadyLoaded = CollectionUtils.newHashSet(expectedExtensionCount);
        for (GradleProjectExtensionDef<?> def: defs2) {
            NbGradleExtensionRef loadedExtension = loadExtension(project, def);
            tryAddExtension(def, loadedExtension, result, alreadyLoaded);
        }

        for (org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery def: defs1) {
            NbGradleExtensionRef loadedExtension = loadExtension(project, def);
            tryAddExtension(def, loadedExtension, result, alreadyLoaded);
        }

        return result;
    }

    /** @deprecated */
    @Deprecated
    private static GradleModelDefQuery1 getModelQuery(
            org.netbeans.gradle.project.api.entry.GradleProjectExtension extension) {

        List<Class<?>> allModels = new LinkedList<>();
        for (List<Class<?>> models: extension.getGradleModels()) {
            allModels.addAll(models);
        }

        final List<Class<?>> toolingModels = Collections.unmodifiableList(allModels);
        return new GradleModelDefQuery1() {
            @Override
            public Collection<Class<?>> getToolingModels(GradleTarget gradleTarget) {
                if (gradleTarget.getJavaVersion().compareTo(JAVA6_VERSION) < 0) {
                    return Collections.emptyList();
                }

                return toolingModels;
            }
        };
    }

    /** @deprecated */
    @Deprecated
    private static GradleProjectExtension2<SerializableLookup> createWrappedProjectExtension(
            final org.netbeans.gradle.project.api.entry.GradleProjectExtension extension) {

        final Lookup permanentLookup = extension.getExtensionLookup();

        return new GradleProjectExtension2<SerializableLookup>() {
            @Override
            public Lookup getPermanentProjectLookup() {
                return permanentLookup;
            }

            @Override
            public Lookup getProjectLookup() {
                return Lookup.EMPTY;
            }

            @Override
            public Lookup getExtensionLookup() {
                return Lookup.EMPTY;
            }

            @Override
            public void activateExtension(SerializableLookup parsedModel) {
                extension.modelsLoaded(parsedModel.lookup);
            }

            @Override
            public void deactivateExtension() {
                extension.modelsLoaded(Lookup.EMPTY);
            }
        };
    }

    private static SerializableLookup serializableLookup(Object... content) {
        return new SerializableLookup(Lookups.fixed(content));
    }

    private static SerializableLookup serializableLookup(Collection<?> content) {
        return serializableLookup(content.toArray());
    }

    private static Map<File, SerializableLookup> serializableLookupMap(Map<File, Lookup> map) {
        Map<File, SerializableLookup> result = CollectionUtils.newHashMap(map.size());
        for (Map.Entry<File, Lookup> entry: map.entrySet()) {
            result.put(entry.getKey(), new SerializableLookup(entry.getValue()));
        }
        return result;
    }

    /** @deprecated */
    @Deprecated
    private static ParsedModel<SerializableLookup> parseModelUsingExtension(
            File projectDir,
            org.netbeans.gradle.project.api.entry.GradleProjectExtension extension,
            Lookup retrievedModels) {

        Map<File, SerializableLookup> deduced = serializableLookupMap(
                extension.deduceModelsForProjects(retrievedModels));

        if (!deduced.containsKey(projectDir)) {
            List<Object> lookupContent = new LinkedList<>();
            for (List<Class<?>> models: extension.getGradleModels()) {
                for (Class<?> neededModel: models) {
                    Object model = retrievedModels.lookup(neededModel);
                    if (model != null) {
                        lookupContent.add(model);
                        break;
                    }
                }
            }

            return new ParsedModel<>(serializableLookup(lookupContent), deduced);
        }

        SerializableLookup mainModels = deduced.get(projectDir);
        if (mainModels != null) {
            deduced = new HashMap<>(deduced);
            deduced.remove(projectDir);
        }

        return new ParsedModel<>(mainModels, deduced);
    }

    /** @deprecated  */
    @Deprecated
    private static GradleProjectExtensionDef<SerializableLookup> createWrappedDef(
            final File projectDirOfExtension,
            final org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery query,
            final org.netbeans.gradle.project.api.entry.GradleProjectExtension extension) {

        return new OldExtensionQueryWrapper(extension, projectDirOfExtension, query);
    }

    private ExtensionLoader() {
        throw new AssertionError();
    }

    /** @deprecated */
    @Deprecated
    @SuppressWarnings("deprecation")
    private static class OldExtensionQueryWrapper implements GradleProjectExtensionDef<SerializableLookup> {
        private final String extensionName;
        private final org.netbeans.gradle.project.api.entry.GradleProjectExtension extension;
        private final Lookup lookup;
        private final File projectDirOfExtension;
        private final org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery query;

        /** @deprecated */
        @Deprecated
        public OldExtensionQueryWrapper(
                org.netbeans.gradle.project.api.entry.GradleProjectExtension extension,
                File projectDirOfExtension,
                org.netbeans.gradle.project.api.entry.GradleProjectExtensionQuery query) {

            this.extensionName = extension.getExtensionName();
            this.extension = extension;
            this.lookup = Lookups.singleton(getModelQuery(extension));
            this.projectDirOfExtension = projectDirOfExtension;
            this.query = query;

            Objects.requireNonNull(extensionName, "GradleProjectExtension.getExtensionName()");
        }

        @Override
        public String getName() {
            return extensionName;
        }

        @Override
        public String getDisplayName() {
            return extension.getExtensionName();
        }

        @Override
        public Lookup getLookup() {
            return lookup;
        }

        @Override
        public Class<SerializableLookup> getModelType() {
            return SerializableLookup.class;
        }

        @Override
        public ParsedModel<SerializableLookup> parseModel(ModelLoadResult modelLoadResult) {
            File projectDir = modelLoadResult.getMainProjectDir();
            Lookup models = modelLoadResult.getMainProjectModels();

            if (projectDir.equals(projectDirOfExtension)) {
                return parseModelUsingExtension(projectDir, extension, models);
            }

            NbGradleProject project = GradleModelLoader.tryFindGradleProject(projectDir);
            if (project == null) {
                LOGGER.log(Level.WARNING, "Could not load Gradle project: {0}", projectDir);
                return ParsedModel.noModels();
            }

            NbGradleExtensionRef extensionToUse = null;
            for (NbGradleExtensionRef projectExtension: project.getExtensionRefs()) {
                if (extensionName.equals(projectExtension.getName())) {
                    extensionToUse = projectExtension;
                    break;
                }
            }

            if (extensionToUse == null) {
                LOGGER.log(Level.WARNING, "Missing extension for project: {0}", projectDir);
                return ParsedModel.noModels();
            }

            GradleProjectExtensionDef<?> extensionDefToUse = extensionToUse.getExtensionDef();
            if (extensionDefToUse instanceof OldExtensionQueryWrapper) {
                OldExtensionQueryWrapper wrapper = (OldExtensionQueryWrapper)extensionDefToUse;

                return parseModelUsingExtension(projectDir, wrapper.extension, models);
            }

            LOGGER.log(Level.WARNING,
                    "Other project does not uses the old format for the same extension. Extension = {0}, Project: {1}",
                    new Object[]{extensionName, projectDir});
            return ParsedModel.noModels();
        }

        @Override
        public GradleProjectExtension2<SerializableLookup> createExtension(Project project) throws IOException {
            // This won't really be called, only implemented for completness sake.
            org.netbeans.gradle.project.api.entry.GradleProjectExtension newExtension
                    = query.loadExtensionForProject(project);

            Objects.requireNonNull(newExtension, "GradleProjectExtensionQuery.loadExtensionForProject");
            return createWrappedProjectExtension(newExtension);
        }

        @Override
        public Set<String> getSuppressedExtensions() {
            return Collections.emptySet();
        }
    }

    private static final class SerializableLookup implements Serializable {
        private static final long serialVersionUID = 1L;

        private final Lookup lookup;

        public SerializableLookup(Lookup lookup) {
            ExceptionHelper.checkNotNullArgument(lookup, "lookup");

            this.lookup = lookup;
        }

        public <T> T lookup(Class<T> clazz) {
            return lookup.lookup(clazz);
        }

        public <T> Collection<? extends T> lookupAll(Class<T> clazz) {
            return lookup.lookupAll(clazz);
        }

        private Object writeReplace() {
            return new SerializedFormat(this);
        }

        private void readObject(ObjectInputStream stream) throws InvalidObjectException {
            throw new InvalidObjectException("Use proxy.");
        }

        private static final class SerializedFormat implements Serializable {
            private static final long serialVersionUID = 1L;

            private final Object[] lookupContent;

            public SerializedFormat(SerializableLookup source) {
                this.lookupContent = filterSerializable(source.lookup.lookupAll(Object.class));
            }

            private static Object[] filterSerializable(Collection<?> objects) {
                List<Object> result = new ArrayList<>(objects.size());
                for (Object obj: objects) {
                    if (obj instanceof Serializable) {
                        result.add(obj);
                    }
                }
                return result.toArray();
            }

            private Object readResolve() throws ObjectStreamException {
                return new SerializableLookup(Lookups.fixed(lookupContent));
            }
        }
    }
}
TOP

Related Classes of org.netbeans.gradle.project.ExtensionLoader$SerializableLookup$SerializedFormat

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.