AbstractXMLServiceManager.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2025 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.generic_project.dao.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import org.openspcoop2.generic_project.beans.IProjectInfo;
import org.openspcoop2.generic_project.exception.ServiceException;
import org.openspcoop2.generic_project.serializer.AbstractDeserializerBase;
import org.openspcoop2.utils.LoggerWrapperFactory;
import org.openspcoop2.utils.xml.ValidatoreXSD;
import org.slf4j.Logger;
/**
* AbstractXMLServiceManager
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public abstract class AbstractXMLServiceManager<XML> {
/** Contesto di Unmarshall. */
private AbstractDeserializerBase deserializer;
private Class<XML> cXmlRoot;
/** XML Path */
protected String xmlPath;
/** 'Root' XML */
protected XML rootXml;
/** XSD Validator */
private ValidatoreXSD xsdValidator = null;
/** LastModified */
private long lastModified = 0;
/** Logger */
private Logger log = null;
/** Refresh Timeout */
private static final int timeoutRefresh = 30;
/** ************* parsing XML ************** */
private void parsingXML() throws ServiceException{
/* --- XSD -- */
FileInputStream fXML = null;
try{
if(this.xmlPath.startsWith("http://") || this.xmlPath.startsWith("file://")){
this.xsdValidator.valida(this.xmlPath);
}else{
fXML = new FileInputStream(this.xmlPath);
this.xsdValidator.valida(fXML);
}
}catch (Exception e) {
throw new ServiceException("Xsd validation failure: "+e.getMessage(),e);
}finally{
if(fXML!=null){
try{
fXML.close();
}catch(Exception e){}
}
}
/* ---- InputStream ---- */
InputStream iStream = null;
HttpURLConnection httpConn = null;
if(this.xmlPath.startsWith("http://") || this.xmlPath.startsWith("file://")){
try{
URL url = new URL(this.xmlPath);
URLConnection connection = url.openConnection();
httpConn = (HttpURLConnection) connection;
httpConn.setRequestMethod("GET");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
iStream = httpConn.getInputStream();
}catch(Exception e) {
try{
// if(iStream!=null)
// iStream.close();
if(httpConn !=null)
httpConn.disconnect();
} catch(Exception ef) {}
throw new ServiceException("Creating InputStream (HTTP) failure: "+e.getMessage(),e);
}
this.lastModified = System.currentTimeMillis();
}else{
try{
iStream = new FileInputStream(this.xmlPath);
}catch(java.io.FileNotFoundException e) {
throw new ServiceException("Creating InputStream (FILE) failure"+e.getMessage(),e);
}
try{
this.lastModified = (new File(this.xmlPath)).lastModified();
}catch(Exception e){
try{
if(iStream!=null)
iStream.close();
} catch(java.io.IOException ef) {}
throw new ServiceException("Reading xml ["+this.xmlPath+"] failure: "+e.getMessage(),e);
}
}
/* ---- Unmarshall ---- */
try{
this.rootXml = (XML) this.deserializer.xmlToObj(iStream, this.cXmlRoot);
} catch(Exception e) {
try{
if(iStream!=null)
iStream.close();
if(httpConn !=null)
httpConn.disconnect();
} catch(Exception ef) {}
throw new ServiceException("Unmarshall document xml failure: "+e.getMessage(),e);
}
/* ---- Close ---- */
try{
if(iStream!=null)
iStream.close();
if(httpConn !=null)
httpConn.disconnect();
} catch(Exception e) {
throw new ServiceException("Close InputStream failure: "+e.getMessage(),e);
}
}
/* ******** COSTRUTTORI e METODI DI RELOAD ******** */
protected AbstractXMLServiceManager(Class<XML> cXmlRoot, AbstractDeserializerBase deserializer, String xsdPath, File xmlPath) throws ServiceException{
this(cXmlRoot, deserializer, xsdPath, xmlPath,null);
}
protected AbstractXMLServiceManager(Class<XML> cXmlRoot, AbstractDeserializerBase deserializer, String xsdPath, File xmlPath,Logger alog) throws ServiceException{
this(cXmlRoot,deserializer, xsdPath, xmlPath.getAbsolutePath(),alog);
}
protected AbstractXMLServiceManager(Class<XML> cXmlRoot, AbstractDeserializerBase deserializer, String xsdPath, String xmlPath) throws ServiceException{
this(cXmlRoot, deserializer, xsdPath, xmlPath,null);
}
protected AbstractXMLServiceManager(Class<XML> cXmlRoot, AbstractDeserializerBase deserializer, String xsdPath, String xmlPath,Logger alog) throws ServiceException{
if(alog==null){
this.log = LoggerWrapperFactory.getLogger(AbstractXMLServiceManager.class);
}else
this.log = alog;
if(xmlPath == null){
this.log.error("New Instance failure: url/xmlPath is null");
throw new ServiceException("New Instance failure: url/xmlPath is null");
}
this.xmlPath = xmlPath;
/* --- XSD Validator -- */
if(xsdPath == null){
this.log.error("New Instance failure: xsdPath is null");
throw new ServiceException("New Instance failure: xsdPath is null");
}
InputStream is = null;
try{
File f = new File(xsdPath);
if(f.exists()){
is = new FileInputStream(f);
}else{
is = cXmlRoot.getResourceAsStream(xsdPath);
if(is==null){
is = cXmlRoot.getResourceAsStream("/"+xsdPath);
}
}
if(is==null){
throw new Exception("Creating InputStream from xsdPath["+xsdPath+"] failure");
}
this.xsdValidator = new ValidatoreXSD(null,is);
}catch (Exception e) {
this.log.error("Init xsd schema failure: "+e.getMessage(),e);
throw new ServiceException("Init xsd schema failure: "+e.getMessage(),e);
}finally{
try{
if(is!=null){
is.close();
}
}catch(Exception eClose){
// close
}
}
/* ---- Uunmarshall ---- */
this.cXmlRoot = cXmlRoot;
this.deserializer = deserializer;
this.parsingXML();
}
public void refreshXML() throws ServiceException{
refreshXML_engine(false);
}
public void refreshXML(boolean forcedWithoutCheckModified) throws ServiceException{
refreshXML_engine(forcedWithoutCheckModified);
}
private synchronized void refreshXML_engine(boolean forcedWithoutCheckModified) throws ServiceException{
File fTest = null;
boolean refresh = forcedWithoutCheckModified;
if(forcedWithoutCheckModified==false){
if(this.xmlPath.startsWith("http://") || this.xmlPath.startsWith("file://")){
long now = System.currentTimeMillis();
if( (now-this.lastModified) > (AbstractXMLServiceManager.timeoutRefresh*1000) ){
refresh=true;
}
}else{
fTest = new File(this.xmlPath);
if(this.lastModified != fTest.lastModified()){
refresh = true;
}
}
}
if(refresh){
try{
this.parsingXML();
}catch(Exception e){
this.log.error("Refresh failure: "+e.getMessage(),e);
throw new ServiceException("Refresh failure: "+e.getMessage(),e);
}
if(this.xmlPath.startsWith("http://")==false && this.xmlPath.startsWith("file://")==false){
this.log.warn("Reloaded context.");
}
}
if(this.rootXml == null){
this.log.error("Refresh failure: rootXml is null after the refresh");
throw new ServiceException("Refresh failure: rootXml is null after the refresh");
}
}
public void checkRemoteXML() throws ServiceException{
if(this.xmlPath.startsWith("http://")){
throw new ServiceException("You can not use the CRUD service with a remote XML");
}
}
public Logger getLog() {
return this.log;
}
public XML getRootXml() {
return this.rootXml;
}
/* Logger */
public static void configureDefaultLog4jProperties(IProjectInfo project) throws ServiceException{
XMLLoggerProperties loggerProperties = new XMLLoggerProperties(project);
loggerProperties.configureLog4j();
}
public static void configureLog4jProperties(File log4jProperties) throws ServiceException{
XMLLoggerProperties loggerProperties = new XMLLoggerProperties(null,log4jProperties);
loggerProperties.configureLog4j();
}
}