diff options
Diffstat (limited to 'plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java')
-rw-r--r-- | plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java new file mode 100644 index 000000000000..8828b9ef5880 --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/ExternalProjectSerializer.java @@ -0,0 +1,262 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed 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.jetbrains.plugins.gradle.service.project.data; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.Serializer; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import com.esotericsoftware.kryo.serializers.CollectionSerializer; +import com.esotericsoftware.kryo.serializers.DefaultSerializers; +import com.esotericsoftware.kryo.serializers.FieldSerializer; +import com.esotericsoftware.kryo.serializers.MapSerializer; +import com.esotericsoftware.minlog.Log; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.externalSystem.model.*; +import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.StreamUtil; +import gnu.trove.THashMap; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.objenesis.strategy.StdInstantiatorStrategy; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.util.*; + +/** + * @author Vladislav.Soroka + * @since 7/15/2014 + */ +public class ExternalProjectSerializer { + private static final Logger LOG = Logger.getInstance(ExternalProjectSerializer.class); + + private final Kryo myKryo; + + public ExternalProjectSerializer() { + myKryo = new Kryo() { + @Override + public <T> T newInstance(Class<T> type) { + LOG.error("Serializing default type: " + type); + return super.newInstance(type); + } + }; + configureKryo(); + } + + private void configureKryo() { + myKryo.setAutoReset(true); + + myKryo.setRegistrationRequired(true); + Log.set(Log.LEVEL_WARN); + + myKryo.register(ArrayList.class, new CollectionSerializer() { + @Override + protected Collection create(Kryo kryo, Input input, Class<Collection> type) { + return new ArrayList(); + } + }); + myKryo.register(HashMap.class, new MapSerializer() { + @Override + protected Map create(Kryo kryo, Input input, Class<Map> type) { + return new HashMap(); + } + }); + myKryo.register(HashSet.class, new CollectionSerializer() { + @Override + protected Collection create(Kryo kryo, Input input, Class<Collection> type) { + return new HashSet(); + } + }); + + myKryo.register(File.class, new FileSerializer()); + myKryo.register(DefaultExternalProject.class, new FieldSerializer<DefaultExternalProject>(myKryo, DefaultExternalProject.class) { + @Override + protected DefaultExternalProject create(Kryo kryo, Input input, Class<DefaultExternalProject> type) { + return new DefaultExternalProject(); + } + }); + + myKryo.register(DefaultExternalTask.class, new FieldSerializer<DefaultExternalTask>(myKryo, DefaultExternalTask.class) { + @Override + protected DefaultExternalTask create(Kryo kryo, Input input, Class<DefaultExternalTask> type) { + return new DefaultExternalTask(); + } + }); + + myKryo.register(DefaultExternalPlugin.class, new FieldSerializer<DefaultExternalPlugin>(myKryo, DefaultExternalPlugin.class) { + @Override + protected DefaultExternalPlugin create(Kryo kryo, Input input, Class<DefaultExternalPlugin> type) { + return new DefaultExternalPlugin(); + } + }); + + myKryo.register(DefaultExternalSourceSet.class, new FieldSerializer<DefaultExternalSourceSet>(myKryo, DefaultExternalSourceSet.class) { + @Override + protected DefaultExternalSourceSet create(Kryo kryo, Input input, Class<DefaultExternalSourceSet> type) { + return new DefaultExternalSourceSet(); + } + }); + + myKryo.register( + DefaultExternalSourceDirectorySet.class, + new FieldSerializer<DefaultExternalSourceDirectorySet>(myKryo, DefaultExternalSourceDirectorySet.class) { + @Override + protected DefaultExternalSourceDirectorySet create(Kryo kryo, Input input, Class<DefaultExternalSourceDirectorySet> type) { + return new DefaultExternalSourceDirectorySet(); + } + } + ); + + myKryo.register(DefaultExternalFilter.class, new FieldSerializer<DefaultExternalFilter>(myKryo, DefaultExternalFilter.class) { + @Override + protected DefaultExternalFilter create(Kryo kryo, Input input, Class<DefaultExternalFilter> type) { + return new DefaultExternalFilter(); + } + }); + + myKryo.register(ExternalSystemSourceType.class, new DefaultSerializers.EnumSerializer(ExternalSystemSourceType.class)); + + myKryo.register(LinkedHashSet.class, new CollectionSerializer() { + @Override + protected Collection create(Kryo kryo, Input input, Class<Collection> type) { + return new LinkedHashSet(); + } + }); + myKryo.register(HashSet.class, new CollectionSerializer() { + @Override + protected Collection create(Kryo kryo, Input input, Class<Collection> type) { + return new HashSet(); + } + }); + myKryo.register(THashSet.class, new CollectionSerializer() { + @Override + protected Collection create(Kryo kryo, Input input, Class<Collection> type) { + return new THashSet(); + } + }); + myKryo.register(Set.class, new CollectionSerializer() { + @Override + protected Collection create(Kryo kryo, Input input, Class<Collection> type) { + return new HashSet(); + } + }); + myKryo.register(THashMap.class, new MapSerializer() { + @Override + protected Map create(Kryo kryo, Input input, Class<Map> type) { + return new THashMap(); + } + }); + } + + + public void save(@NotNull ExternalProject externalProject) { + Output output = null; + try { + final String externalProjectPath = externalProject.getProjectDir().getPath(); + final File configurationFile = + getProjectConfigurationFile(new ProjectSystemId(externalProject.getExternalSystemId()), externalProjectPath); + if (!FileUtil.createParentDirs(configurationFile)) return; + + output = new Output(new FileOutputStream(configurationFile)); + myKryo.writeObject(output, externalProject); + } + catch (FileNotFoundException e) { + LOG.error(e); + } + finally { + StreamUtil.closeStream(output); + } + } + + @Nullable + public ExternalProject load(@NotNull ProjectSystemId externalSystemId, File externalProjectPath) { + Input input = null; + try { + final File configurationFile = getProjectConfigurationFile(externalSystemId, externalProjectPath.getPath()); + if (!configurationFile.isFile()) return null; + + input = new Input(new FileInputStream(configurationFile)); + return myKryo.readObject(input, DefaultExternalProject.class); + } + catch (Exception e) { + LOG.error(e); + } + finally { + StreamUtil.closeStream(input); + } + + return null; + } + + private static File getProjectConfigurationFile(ProjectSystemId externalSystemId, String externalProjectPath) { + return new File(getProjectConfigurationDir(externalSystemId), Integer.toHexString(externalProjectPath.hashCode()) + "/project.dat"); + } + + private static File getProjectConfigurationDir(ProjectSystemId externalSystemId) { + return getPluginSystemDir(externalSystemId, "Projects"); + } + + private static File getPluginSystemDir(ProjectSystemId externalSystemId, String folder) { + return new File(PathManager.getSystemPath(), externalSystemId.getId().toLowerCase() + "/" + folder).getAbsoluteFile(); + } + + private static class FileSerializer extends Serializer<File> { + private final Kryo myStdKryo; + + public FileSerializer() { + myStdKryo = new Kryo(); + myStdKryo.register(File.class); + myStdKryo.setInstantiatorStrategy(new StdInstantiatorStrategy()); + } + + @Override + public void write(Kryo kryo, Output output, File object) { + myStdKryo.writeObject(output, object); + } + + @Override + public File read(Kryo kryo, Input input, Class<File> type) { + File file = myStdKryo.readObject(input, File.class); + return new File(file.getPath()); + } + } + + private static class StdSerializer<T> extends Serializer<T> { + private final Kryo myStdKryo; + + public StdSerializer(Class<T> clazz) { + myStdKryo = new Kryo(); + myStdKryo.register(clazz); + myStdKryo.setInstantiatorStrategy(new StdInstantiatorStrategy()); + } + + @Override + public void write(Kryo kryo, Output output, T object) { + myStdKryo.writeObject(output, object); + } + + @Override + public T read(Kryo kryo, Input input, Class<T> type) { + return myStdKryo.readObject(input, type); + } + } +} |