Why we need to copy XSD files to source repo?

Problem Statement: From production Spring application can’t access spring servers for XSD files.
It is better to keep XSD files along with source code for following reasons.
1. Easy to access local system, rather going outside network. (Security issues)
2. Sometimes third party sites are down. During that we can’t do anything.

Solution:
If we have more than 10 files, it is difficult to copy manually those XSD files and prepare mapping files in spring.schemas file. For this reason, I written this code.
Input: Search all xml files and find list of XSDs referred in source code. Use text editor and xls to sort them and remove duplicates. Put list of URLs in input_xsd_urls.txt file.
Example:
http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context/spring-context-3.0.xsd

Output:
This program creates folders in given path and copy files from respective source.
At the end it gives mapping to put in spring.schemas file. Issue solved.

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;

/**
 * This is used to download XSD files to respective locations.
 * 
 * @author Bhavani P Polimetla
 * @since 11/29/2012
 * 
 */
public class XSDDownloader {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String ROOT = "C:/xsd_download/";
		StringBuffer mappingFile = new StringBuffer();

		// Step 1: Read input file and load it
		List<String> list = getXSDURLsList(ROOT + "input_xsd_urls.txt");

		// Step 2: Create folders in given location
		for (String file : list) {

			try {
				URL aURL = new URL(file);
				System.out.println("path = " + aURL.getPath());
				String[] parts = aURL.getPath().split("/");

				StringBuffer sbPart = new StringBuffer();
				for (int i = 0; i < parts.length - 1; i++) {
					sbPart.append(parts[i]).append("/");
				}
				String targetDir = ROOT + "/META-INF/xsd/" + sbPart.toString();

				System.out.println("folder path==>" + targetDir);

				// Create Directories
				File dir = new File(targetDir);
				dir.mkdirs();

				// Download File
				String targetFile = ROOT + "/META-INF/xsd/" + aURL.getPath();
				downloadFile(file, targetFile);

				// Create Mapping File
				// http://drools.org/schema/drools-service-spring.xsd=drools-service-spring.xsd
				mappingFile.append(file).append("=").append("/META-INF/xsd/")
						.append(aURL.getPath()).append("n");

			} catch (MalformedURLException e) {
				e.printStackTrace();
			}

			// during test, comment this.
			// break;
		} // End of for loop

		System.out.println("Add this to spring.schemas file==>");
		String mappingContent = mappingFile.toString();
		mappingContent = mappingContent.replaceAll("//", "/");
		mappingContent = mappingContent.replaceAll("http:", "http\\:/");
		System.out.println(mappingContent);

	}

	/**
	 * Download file from URL to given file location.
	 * 
	 * @param url
	 * @param destinationFile
	 */
	public static void downloadFile(String url, String destinationFile) {
		try {
			URL website = new URL(url);
			ReadableByteChannel rbc = Channels.newChannel(website.openStream());
			FileOutputStream fos = new FileOutputStream(destinationFile);
			fos.getChannel().transferFrom(rbc, 0, 1 << 24);
			fos.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * The file contains
	 * http://www.springframework.org/schema/batch/spring-batch-2.1.xsd one
	 * entry like this in each file.
	 * 
	 * @param fileName
	 * @return
	 */
	public static List<String> getXSDURLsList(String fileName) {
		List<String> files = new ArrayList<String>();
		try {
			// Open the file that is the first
			// command line parameter
			FileInputStream fstream = new FileInputStream(fileName);
			// Get the object of DataInputStream
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			// Read File Line By Line
			while ((strLine = br.readLine()) != null) {
				// Print the content on the console
				System.out.println(strLine);
				files.add(strLine);
			}
			// Close the input stream
			in.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}

		return files;
	}

}

References:
http://stackoverflow.com/questions/1729307/spring-schemalocation-fails-when-there-is-no-internet-connection
https://code.google.com/p/spring-crypto-utils/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s