Thursday, March 29, 2012

Do you want to migrate layers from Geoserver 1.7 to 2.1? ... here is procedure for styles ...

keywords: java, geoserver, SLD migration, File, FileWriter, FilenameFilter, HSQL

...maybe some of you still have Geoserver 1.7 running in production environment and you plan to migrate to version 2.1. Recently I had a similar task … if you have a lot of layers and lot of styles it can be a pretty boring job :-)

To help a little bit I have wrote java class that can help you with style migration. It was a easy task. Maybe I’ll also post application for layer migration … (if I develop one) …. There is a source code for SLD migration at the end of post. Included MD5 method is not necessary but you have to provide unique ID for style. Besides, I don’t take credit for md5 because I found it on internet (don’t remember link …sorry to author).... it seems that works good. For java novice this can be reference how to list folder using filter and how to write to file. Hope that this helps someone ....

Be careful if you already have some features published on Geoserver 2.1. Do not run application directly in styles folder because you can overwrite already used sld files, the value in xml file will be changed and the layer that uses that style will be invalid (Geoserver 2.1. for every sld file have xml file with the same name). Use application in the separate folder and then copy all files (sld and matching xml) into the geoservers style folder. … hmmm you will have to restart geoserver... I’m not sure (but it is easy to check) to avoid any problem that can happen first stop geoserver than copy files and start it again.

There is hsql database that is created when you start geoserver. Some values are stored in it and it can produce problem when you change something directly in folders (without geoserver). If you run into some problems you can delete database in the container temp folder ( Djava.io.tmpdir\Geotools\Databases\HSQL\v7.9.0). When you delete v7.9.0 folder after restart the new folder will be created. I use: Tomcat 7.0.26; Geoserver 2.1.3 rev.16668; GeoTools Version 2.7.4 rev.38443. You may have some other folder but principle is the same … if Geoserver hangs, delete hsql and restart Tomcat :-)

Anyway if you have 100 SLD files it is much easier to stop and start geoserver than to work with one style at the time ... 

... enjoy! 


package my.util.migration.sld;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;

public class XMLGenerator {
    
    private  String getStyleTemplate(){
        String xmlTemplate ="";
        xmlTemplate = xmlTemplate + "<style>\n";
        xmlTemplate = xmlTemplate + "  <id>:style_id:</id>\n";
        xmlTemplate = xmlTemplate + "  <name>:style_name:</name>\n";
        xmlTemplate = xmlTemplate + "  <sldVersion>\n";
        xmlTemplate = xmlTemplate + "    <version>1.0.0</version>\n";
        xmlTemplate = xmlTemplate + "  </sldVersion>\n";
        xmlTemplate = xmlTemplate + "  <filename>:style_filename:</filename>\n";
        xmlTemplate = xmlTemplate + "</style>";
        
        return xmlTemplate;
    }
    
    public void createXML(String sld_file_name, String xmlTemplate, String dest_path){
        String xmName = sld_file_name.replace(".sld",".xml");
        
        xmlTemplate = xmlTemplate.replace(":style_id:", MD5(sld_file_name));
        xmlTemplate = xmlTemplate.replace(":style_name:", sld_file_name.replace(".sld",""));
        xmlTemplate = xmlTemplate.replace(":style_filename:", sld_file_name );
        
        
        FileWriter fstream;
        try {
            
            File f = new File(dest_path);
            fstream = new FileWriter(f.getAbsolutePath() + File.separator + xmName);

            BufferedWriter out = new BufferedWriter(fstream);
            out.write(xmlTemplate);
            //Close the output stream
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }        
    }
    
    public String MD5(String md5) {
           try {
                java.security.MessageDigest md = 
                  java.security.MessageDigest.getInstance("MD5");
                byte[] array = md.digest(md5.getBytes());
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < array.length; ++i) {
                  sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
               }
                return sb.toString();
            } catch (java.security.NoSuchAlgorithmException e) {
            }
            return null;
        }
    
    public void prepareForGS21(String old_path){
        
        XMLGenerator xmlg = new XMLGenerator();
        File f = new File(old_path);
        
        FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
                name=name.toLowerCase();
                return name.endsWith(".sld");
            }
        };
        
        String [] files ;
        files = f.list(filter);
        
        if(files.length !=0){
            for(int i=0; i< files.length; i++){
                //System.out.println(files[i]);
                xmlg.createXML(files[i],xmlg.getStyleTemplate(), old_path);
            }
        }
    }

    
    public static void main(String[] args) {
        XMLGenerator xmlg = new XMLGenerator();
        String path;
        
        if(args.length > 0){
            path = args[0];
        }else{
            System.out.println("XMLGenerator <path>");
            System.out.println("path:\tFolder with the old SLD files\n\tIt will be used as a destination folder for xml files used by Geoserver 2.1");
            System.out.println("\tFor testing u can use /tmp/test or c:\\tmp\\test folder. No need to enter value for path.");
            path = File.separator + "tmp" + File.separator + "test"; 
        }
        xmlg.prepareForGS21(path);   
    }
}

No comments:

Post a Comment