/* * 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.generator.cache; import jetbrains.mps.vfs.IFile; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.jetbrains.annotations.NotNull; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; /** * Facility to mimic try-with-resource clause, to ensure streams are closed once parse is complete * * @author Artem Tikhomirov */ public final class ParseFacility<T> { private final Class<?> myOwner; private final Parser<T> myParser; private IFile myFile; private URL myUrl; public ParseFacility(Class<?> owner, @NotNull Parser<T> parser) { myOwner = owner; myParser = parser; } public ParseFacility<T> input(IFile file) { myFile = file; myUrl = null; return this; } public ParseFacility<T> input(URL url) { myFile = null; myUrl = url; return this; } public boolean isValidInput() { if (myFile != null) { return myFile.exists() && myFile.length() > 0; } if (myUrl != null) { return true; } return false; } /** * Parse and ignore errors, if any * * @return <code>null</code> if didn't succeed */ public T parseSilently() { if (!isValidInput()) { return null; } try { return parse(); } catch (FileNotFoundException ex) { // ok, just ignore } catch (IOException ex) { getLog().warn("Ignored parse error in file " + myFile == null ? null : myFile.getPath(), ex); } return null; } public T parse() throws IOException { InputStream is = null; try { is = openStream(); return myParser.load(is); } finally { closeSilently(is); } } private InputStream openStream() throws IOException { assert isValidInput(); if (myFile != null) { return myFile.openInputStream(); } return myUrl.openStream(); } private void closeSilently(InputStream is) { if (is == null) { return; } try { is.close(); } catch (IOException ex) { getLog().error("Failed to close stream", ex); } } private Logger getLog() { return LogManager.getLogger(myOwner); } public interface Parser<T> { T load(InputStream is) throws IOException; } }