/*
* Copyright 2003-2016 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 jetbrains.mps.make.java;
import jetbrains.mps.cleanup.CleanupManager;
import jetbrains.mps.generator.GenerationStatus;
import jetbrains.mps.generator.cache.BaseModelCache;
import jetbrains.mps.generator.cache.CacheGenerator;
import jetbrains.mps.generator.cache.ParseFacility;
import jetbrains.mps.generator.cache.ParseFacility.Parser;
import jetbrains.mps.generator.generationTypes.StreamHandler;
import jetbrains.mps.generator.impl.dependencies.GenerationRootDependencies;
import jetbrains.mps.util.FileUtil;
import jetbrains.mps.util.JDOMUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.module.SRepository;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class BLDependenciesCache extends BaseModelCache<ModelDependencies> {
private static BLDependenciesCache INSTANCE;
public static BLDependenciesCache getInstance() {
return INSTANCE;
}
public BLDependenciesCache(SRepository repository, CleanupManager manager) {
super(repository, manager);
}
@Override
public void init() {
if (INSTANCE != null) {
throw new IllegalStateException("double initialization");
}
INSTANCE = this;
super.init();
}
@Override
public void dispose() {
super.dispose();
INSTANCE = null;
}
@Override
@NotNull
public String getCacheFileName() {
return "dependencies";
}
public CacheGenerator newCacheGenerator(@Nullable ModelDependencies newDeps) {
return new CacheGen(newDeps);
}
@Nullable
@Override
protected ModelDependencies readCache(SModel sm) {
return new ParseFacility<ModelDependencies>(getClass(), new CacheParser()).input(getCacheFile(sm)).parseSilently();
}
private class CacheGen implements CacheGenerator {
private final ModelDependencies myDepsNew;
public CacheGen(ModelDependencies newDeps) {
myDepsNew = newDeps;
}
@Override
public void generateCache(GenerationStatus status, StreamHandler handler) {
final ModelDependencies deps = updateUnchanged(status);
if (deps == null) {
return;
}
update(status.getOriginalInputModel(), deps);
handler.saveStream(getCacheFileName(), deps.toXml());
}
private ModelDependencies updateUnchanged(GenerationStatus genStatus) {
if (myDepsNew == null) {
return null;
}
// update modelDependencies and generationDependencies
ModelDependencies modelDep = null;
// process unchanged files
SModel originalInputModel = genStatus.getOriginalInputModel();
for (GenerationRootDependencies rdep : genStatus.getDependencies().getUnchangedDependencies()) {
for (String filename : rdep.getFiles()) {
// re-register baseLanguage dependencies
if (modelDep == null) {
modelDep = BLDependenciesCache.getInstance().get(originalInputModel);
}
if (modelDep != null) {
RootDependencies root = modelDep.getDependency(filename);
if (root != null) {
myDepsNew.replaceRoot(root);
}
}
}
}
return myDepsNew;
}
}
private static class CacheParser implements Parser<ModelDependencies> {
@Override
public ModelDependencies load(InputStream is) throws IOException {
try {
SAXParser saxParser = JDOMUtil.createSAXParser();
BLDependenciesHandler handler = new BLDependenciesHandler();
saxParser.parse(new InputSource(new InputStreamReader(is, FileUtil.DEFAULT_CHARSET)), handler);
ModelDependencies dependencies = handler.getResult();
if (dependencies != null) {
return dependencies;
}
throw new IOException("empty result");
} catch (SAXException ex) {
throw new IOException(ex);
} catch (ParserConfigurationException ex) {
throw new IOException(ex);
}
}
}
}