/*
* Copyright 2003-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 jetbrains.mps.persistence;
import jetbrains.mps.extapi.model.SModelData;
import jetbrains.mps.generator.ModelDigestUtil;
import jetbrains.mps.smodel.SModelHeader;
import jetbrains.mps.smodel.loading.ModelLoadResult;
import jetbrains.mps.smodel.loading.ModelLoadingState;
import jetbrains.mps.smodel.persistence.def.ModelReadException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.persistence.DataSource;
import org.jetbrains.mps.openapi.persistence.ModelFactory;
import org.jetbrains.mps.openapi.persistence.StreamDataSource;
import java.io.IOException;
import java.util.Map;
/**
* Internal facility around ModelFactory which is aware of partial loading approach.
* Initially, just an extraction of differences between LazyEditableSModelBase subclasses (DefaultSModelDescriptor, BinarySModelDescriptor and
* FilePerRootSModel), hence awkward API.
*
* @author Artem Tikhomirov
*/
public abstract class LazyLoadFacility {
private final ModelFactory myModelFactory;
private final DataSource mySource;
public LazyLoadFacility(@NotNull ModelFactory modelFactory, @NotNull DataSource dataSource) {
myModelFactory = modelFactory;
mySource = dataSource;
}
@NotNull
public ModelFactory getModelFactory() {
return myModelFactory;
}
@NotNull
public DataSource getSource() {
return mySource;
}
public String getModelHash() {
// FIXME refactor DataSource to answer hash()/digest() queries itself (and move this code back to generatable model impl)
String modelHash = ModelDigestHelper.getInstance().getModelHash((StreamDataSource) getSource());
if (modelHash != null) {
return modelHash;
}
return ModelDigestUtil.hash((StreamDataSource) getSource(), !getModelFactory().isBinary());
}
public abstract Map<String, String> getGenerationHashes();
@NotNull
public abstract SModelHeader readHeader() throws ModelReadException;
@NotNull
public abstract ModelLoadResult readModel(@NotNull SModelHeader header, @NotNull ModelLoadingState state) throws ModelReadException;
/**
* The method is quite questionable, though better than saveModel returning != null value to indicate persistence has changed during save.
* One of alternatives is to alter header's field (persistenceVersion) on saveModel so that caller gets a chance to find out persistence had changed
* @return true if model could not be saved with persistence version indicated in the header.
*/
public abstract boolean doesSaveUpgradePersistence(@NotNull SModelHeader header);
public abstract void saveModel(@NotNull SModelHeader header, SModelData modelData) throws IOException;
}