/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ package de.cismet.cismap.commons.capabilities; import org.apache.log4j.Logger; import java.net.MalformedURLException; import de.cismet.security.exceptions.AccessMethodIsNotSupportedException; import de.cismet.security.exceptions.MissingArgumentException; import de.cismet.security.exceptions.NoHandlerForURLException; import de.cismet.security.exceptions.RequestFailedException; /** * DOCUMENT ME! * * @author therter * @version $Revision$, $Date$ */ public abstract class AbstractVersionNegotiator { //~ Static fields/initializers --------------------------------------------- private static Logger logger = Logger.getLogger(AbstractVersionNegotiator.class); private static final String VERSION_STRING = "version"; // NOI18N //~ Instance fields -------------------------------------------------------- // the constant SUPPORTED_VERSIONS contains all supported service versions. The array should // be sorted and the first elements of the array should contain the oldest version. protected String[] supportedVersions; // NOI18N protected String currentVersion = null; protected String serviceName; //~ Constructors ----------------------------------------------------------- /** * Creates a new AbstractVersionNegotiator object. */ public AbstractVersionNegotiator() { initVersion(); } //~ Methods ---------------------------------------------------------------- /** * This m,ethod must be overidden by the sub classes and should initialize the constant SUPPORTED_VERSIONS. */ protected abstract void initVersion(); /** * Invokes the GetCapabilities operation of the server with an older version string. * * @param link DOCUMENT ME! * * @return DOCUMENT ME! * * @throws MalformedURLException DOCUMENT ME! * @throws MissingArgumentException DOCUMENT ME! * @throws AccessMethodIsNotSupportedException DOCUMENT ME! * @throws RequestFailedException DOCUMENT ME! * @throws NoHandlerForURLException DOCUMENT ME! * @throws Exception DOCUMENT ME! */ protected String getOlderCapabilitiesDocument(String link) throws MalformedURLException, MissingArgumentException, AccessMethodIsNotSupportedException, RequestFailedException, NoHandlerForURLException, Exception { final StringBuilder document; boolean olderVersionFound = false; if (logger.isDebugEnabled()) { logger.debug("try to use an older version number"); // NOI18N } for (int i = 1; i < supportedVersions.length; ++i) { if (supportedVersions[i].equals(currentVersion)) { currentVersion = supportedVersions[i - 1]; olderVersionFound = true; } } if (olderVersionFound) { if (logger.isDebugEnabled()) { logger.debug("Older version found " + currentVersion); // NOI18N } if (link.toLowerCase().indexOf("?") != -1) { // NOI18N link = link.substring(0, link.toLowerCase().indexOf("?")); // NOI18N } link += "?SERVICE=" + serviceName + "&REQUEST=GetCapabilities&VERSION=" + currentVersion; // NOI18N document = readStringFromlink(link); return document.toString(); } return null; } /** * DOCUMENT ME! * * @param link DOCUMENT ME! * * @return the capabilities document of the service with the given link. If the link already contains a version, * then this version will be used as start version for the version negotation. Otherwise, the most recent * version, that is supported by the client will be used as start version. * * @throws MalformedURLException DOCUMENT ME! * @throws MissingArgumentException DOCUMENT ME! * @throws AccessMethodIsNotSupportedException DOCUMENT ME! * @throws RequestFailedException DOCUMENT ME! * @throws NoHandlerForURLException DOCUMENT ME! * @throws Exception DOCUMENT ME! */ protected String getCapabilitiesDocument(String link) throws MalformedURLException, MissingArgumentException, AccessMethodIsNotSupportedException, RequestFailedException, NoHandlerForURLException, Exception { String startVersion = getVersionFromLink(link); final StringBuilder document; if (startVersion == null) { if (logger.isDebugEnabled()) { logger.debug("No version string found in the link: " + link); // NOI18N } // set the version to the latest one startVersion = supportedVersions[supportedVersions.length - 1]; } if (link.indexOf("?") != -1) { // NOI18N // some GetCapabilities links contains special parameter, which should not cut off if (link.toLowerCase().indexOf("version") == -1) { // NOI18N link += "&VERSION=" + startVersion; } else { String linkTmp = link.substring(0, link.toLowerCase().indexOf("version") + "version".length()); linkTmp += "=" + startVersion; int indexAfterVersionString = link.toLowerCase().indexOf("version"); for (; indexAfterVersionString < link.length(); ++indexAfterVersionString) { if (link.charAt(indexAfterVersionString) == '&') { break; } } if (indexAfterVersionString < link.length()) { linkTmp += link.substring(indexAfterVersionString); } link = linkTmp; } } else { link += "?SERVICE=" + serviceName + "&REQUEST=GetCapabilities&VERSION=" + startVersion; // NOI18N } if (link.indexOf("?") != -1) { final String parameter = link.substring(link.indexOf("?")); if (parameter.toLowerCase().indexOf("request") == -1) { link += "&REQUEST=GetCapabilities"; } if (parameter.toLowerCase().indexOf("service") == -1) { link += "&SERVICE=" + serviceName; } } if (logger.isDebugEnabled()) { logger.debug("send request = " + link); // NOI18N logger.debug("start version = " + startVersion); // NOI18N } document = readStringFromlink(link); currentVersion = getDocumentVersion(document); if (currentVersion == null) { logger.error("No version string found in the GetCapabilities document from location " + link); // NOI18N // try to parse the document return document.toString(); } if (!isVersionSupported(currentVersion)) { logger.error("The client does not support the version of the received Getcapabilities document." // NOI18N + "\nLink: " + link + "\nresponse version " + currentVersion); // NOI18N } else { if (logger.isDebugEnabled()) { logger.debug("Version negotation successfully. \nLink: " // NOI18N + link + "\nresponse version " + currentVersion); // NOI18N } } return document.toString(); } /** * DOCUMENT ME! * * @param link DOCUMENT ME! * * @return the version string of the given link or null, if the given link does not contain any version string */ protected String getVersionFromLink(final String link) { String version = null; if (link.toLowerCase().indexOf(VERSION_STRING) != -1) { version = link.substring(link.toLowerCase().indexOf(VERSION_STRING) + VERSION_STRING.length() + 1); if (version.indexOf("&") != -1) { // NOI18N version = version.substring(0, version.indexOf("&")); // NOI18N } } return version; } /** * DOCUMENT ME! * * @param version the version that should be checked * * @return true, if the given version is contained in the array constant <code>SUPPORTED_VERSIONS</code> */ private boolean isVersionSupported(final String version) { for (int i = 0; i < supportedVersions.length; ++i) { if (supportedVersions[i].equals(version)) { return true; } } return false; } /** * DOCUMENT ME! * * @param document the GetCapabilities document * * @return the version of the given document or null, if no version string found */ protected String getDocumentVersion(final StringBuilder document) { String documentVersion = null; int startIndexOfVersion = -1; String endCharacter = "\""; if (document.indexOf("?>") != -1) { // NOI18N if (document.indexOf(VERSION_STRING + "=\"", document.indexOf("?>")) == -1) { startIndexOfVersion = document.indexOf(VERSION_STRING + "='", document.indexOf("?>")) // NOI18N + VERSION_STRING.length() + 2; // NOI18N endCharacter = "'"; } else { startIndexOfVersion = document.indexOf(VERSION_STRING + "=\"", document.indexOf("?>")) // NOI18N + VERSION_STRING.length() + 2; // NOI18N } } else { if (document.indexOf(VERSION_STRING + "=\"") == -1) { startIndexOfVersion = document.indexOf(VERSION_STRING + "='") + VERSION_STRING.length() + 2; // NOI18N endCharacter = "'"; } else { startIndexOfVersion = document.indexOf(VERSION_STRING + "=\"") + VERSION_STRING.length() + 2; // NOI18N } } if (startIndexOfVersion != (VERSION_STRING.length() + 1)) { // version string in document found final int endIndexOfVersion = document.indexOf(endCharacter, startIndexOfVersion); // NOI18N documentVersion = document.substring(startIndexOfVersion, endIndexOfVersion); } if (logger.isDebugEnabled()) { logger.debug("version of received GetCapabilities document: " + documentVersion); // NOI18N } return documentVersion; } /** * read the document from the given link. * * @param url DOCUMENT ME! * * @return a StringBuilder that contains the content of the given url * * @throws MalformedURLException DOCUMENT ME! * @throws MissingArgumentException DOCUMENT ME! * @throws AccessMethodIsNotSupportedException DOCUMENT ME! * @throws RequestFailedException DOCUMENT ME! * @throws NoHandlerForURLException DOCUMENT ME! * @throws Exception DOCUMENT ME! */ private StringBuilder readStringFromlink(final String url) throws MalformedURLException, MissingArgumentException, AccessMethodIsNotSupportedException, RequestFailedException, NoHandlerForURLException, Exception { final CapabilitiesCache cache = CapabilitiesCache.getInstance(); return new StringBuilder(cache.calcValue(url)); } }