View Javadoc
1   /**
2    * @(#)GeneticAlgorithmXmlSaxParserFactory.java
3    * Copyright (C) 2008-2011 delhezi.com
4    *
5    * This class is released under the:
6    * GNU Lesser General Public License (LGPL) version 3 or later.
7    * http://www.gnu.org/copyleft/lesser.html
8    */
9   package com.delhezi.ga;
10  
11  import java.io.IOException;
12  import java.io.InputStream;
13  import javax.xml.parsers.ParserConfigurationException;
14  import javax.xml.parsers.SAXParser;
15  import javax.xml.parsers.SAXParserFactory;
16  import javax.xml.transform.Source;
17  import javax.xml.transform.stream.StreamSource;
18  import javax.xml.validation.SchemaFactory;
19  import org.xml.sax.Attributes;
20  import org.xml.sax.InputSource;
21  import org.xml.sax.SAXException;
22  import org.xml.sax.helpers.DefaultHandler;
23  import org.xml.sax.XMLReader;
24  import org.xml.sax.ErrorHandler;
25  import org.xml.sax.SAXParseException;
26  import java.util.logging.Level;
27  import java.util.logging.Logger;
28  import java.util.LinkedList;
29  import com.delhezi.ga.crossover.factory.CrossoverOperatorType;
30  import com.delhezi.ga.exception.GeneticAlgorithmException;
31  import com.delhezi.ga.initialize.data.SampleTsp;
32  import com.delhezi.ga.fitnessfunction.FitnessFunction;
33  import com.delhezi.ga.fitnessfunction.drivers.IFitnessFunctionDriver;
34  import com.delhezi.ga.fitnessfunction.drivers.factory.FitnessFunctionDriverFactory;
35  import com.delhezi.ga.fitnessfunction.FitnessFunctionOption;
36  import com.delhezi.ga.mutation.factory.MutationOperatorType;
37  import com.delhezi.ga.selection.factory.SelectionMethodType;
38  
39  /**
40   * <code>GeneticAlgorithmXmlSaxParserFactory</code>: Analiza składniwa dokumentu xml
41   * z użyciem parsera JAXP. Walidacja w oparciu o newInstanceParameters.xsd
42   * @version 1.0 2009-12-14
43   * @author <a href="mailto:wojciech.wolszczak@delhezi.com">
44   * Wojciech Wolszczak</a>
45   */
46  public class GeneticAlgorithmXmlSaxParserFactory {
47  
48      /** Logger object. */
49      private static final Logger LOGGER =
50          Logger.getLogger(GeneticAlgorithmXmlSaxParserFactory.class.getName());
51  
52      /** Delhezi Error Code. */
53      //private static final String DERC = "1-5-";
54  
55      /** Źródło inicjalizacji populacji. */
56      public static enum InitializeDataSource {
57          /** Baza danych. */
58          db,
59  
60          /** Przykład komiwojażera. */
61          sampleTSP;
62      }
63      private static final String XML_SCHEMA_FILE = "newInstanceParameters.xsd";
64      private GeneticAlgorithm ga;
65  
66      public GeneticAlgorithm newGeneticAlgorithm(
67              final String fitnassFunctionScriptsPath,
68              final String xmlParams) throws GeneticAlgorithmException {
69  
70          ga = new GeneticAlgorithm();
71  
72          DefaultHandler handler = new DefaultHandler() {
73              String currTag;
74              Population population;
75              PopulationType populationType;
76              CrossoverOperatorType crossoverOperator;
77              double crossoverProbability;
78              MutationOperatorType mutationOperator;
79              double mutationProbability;
80              boolean elitism;
81              String fitnessFunctionScript;
82              FitnessFunctionOption fitnessFunctionOption;
83              SelectionMethodType selectionMethod;
84              int maxLT;
85              int minLT;
86              InitializeDataSource initializeDataSource;
87              String initializePopulationConnectionName;
88              String initializePopulationSQLQuery;
89              int populationSize;
90  
91              @Override
92              public void startElement(String uri, String localName,
93                                       String qName,
94                                       Attributes attributes) throws SAXException {
95                  currTag = qName;
96                  if (qName.equalsIgnoreCase("changeablePopulationSize")) {
97                      populationType = PopulationType.PopulationChangeableSize;
98                  } else if (qName.equalsIgnoreCase("constantPopulationSize")) {
99                      populationType = PopulationType.PopulationConstantSize;
100                 } else if (qName.equalsIgnoreCase("elitism")) {
101                     elitism = true; //Jeśli występuje pusty element to domyślnie jest true
102                 } else if (qName.equalsIgnoreCase("db")) {
103                     initializeDataSource = com.delhezi.ga.GeneticAlgorithmXmlSaxParserFactory.InitializeDataSource.db;
104                 } else if (qName.equalsIgnoreCase("sampleTSP")) {
105                     initializeDataSource = com.delhezi.ga.GeneticAlgorithmXmlSaxParserFactory.InitializeDataSource.sampleTSP;
106                 }
107             }
108 
109             @Override
110             public void endDocument() throws SAXException {
111               FitnessFunction fitnessFunction;
112               IFitnessFunctionDriver fitnessFunctionDriver;
113                 try {
114                   fitnessFunctionDriver =
115                                     FitnessFunctionDriverFactory.getFitnessFunctionEngineDriver("javascript",
116                                                                                                 fitnassFunctionScriptsPath,
117                                                                                                 fitnessFunctionScript);
118                     fitnessFunction = new FitnessFunction(fitnessFunctionDriver, "fitnessFunction");
119                 } catch (GeneticAlgorithmException ex) {
120                   LOGGER.log(Level.SEVERE, null, ex);
121                   throw new SAXException(ex.getMessage());
122                 }
123                 if (fitnessFunctionOption == FitnessFunctionOption.minimisation) {
124                   fitnessFunction.setMaximisation(false);
125               } else if (fitnessFunctionOption == FitnessFunctionOption.maximisation) {
126                   fitnessFunction.setMaximisation(true);
127                 }
128 
129                 ChromosomeProperties chromosomeProperties =
130                     ChromosomeProperties.getInstance();
131                 chromosomeProperties.setFitnessFunction(fitnessFunction);
132 
133                 LinkedList<Chromosome> chromosomes = null;
134                 switch (initializeDataSource) {
135               case sampleTSP:
136                     chromosomes = SampleTsp.newChromosomes(populationSize, chromosomeProperties);
137                     break;
138               case db:
139                     //UZUPEŁNIĆ
140                     //initializePopulationConnectionName
141                     //initializePopulationSQLQuery
142                     chromosomes = null;
143                     break;
144                   }
145 
146               switch (populationType) {
147               case PopulationChangeableSize:
148                     try {
149                         population = PopulationChangeableSize.newPopulationChangeableSize(
150                             maxLT, minLT, chromosomes,
151                             crossoverOperator, crossoverProbability,
152                             mutationOperator, mutationProbability,
153                             chromosomeProperties);
154                       } catch (GeneticAlgorithmException ex) {
155                           LOGGER.log(Level.SEVERE, null, ex);
156                           throw new SAXException(ex.getMessage());
157                       }
158                     break;
159               case PopulationConstantSize:
160                     try {
161                         population = PopulationConstantSize.newPopulationConstantSize(
162                             selectionMethod, chromosomes,
163                             crossoverOperator, crossoverProbability,
164                             mutationOperator, mutationProbability,
165                             chromosomeProperties);
166                       } catch (GeneticAlgorithmException ex) {
167                           LOGGER.log(Level.SEVERE, null, ex);
168                           throw new SAXException(ex.getMessage());
169                       }
170                     break;
171                   }
172               ga.setPopulation(population);
173               ga.setState(GeneticAlgorithmState.INITIALIZED);
174             }
175 
176             @Override
177             public void characters(char[] ch, int start,
178                                    int length) throws SAXException {
179                 if (currTag.equalsIgnoreCase("maxLT")) {
180                     maxLT = Integer.parseInt(new String(ch, start, length));
181                 } else if (currTag.equalsIgnoreCase("minLT")) {
182                     minLT = Integer.parseInt(new String(ch, start, length));
183                 } else if (currTag.equalsIgnoreCase("selectionMethod")) {
184                     selectionMethod =
185                             SelectionMethodType.valueOf(new String(ch, start,
186                                                                    length));
187                 } else if (currTag.equalsIgnoreCase("crossoverOperator")) {
188                     crossoverOperator =
189                             CrossoverOperatorType.valueOf(new String(ch, start,
190                                                                      length));
191                 } else if (currTag.equalsIgnoreCase("crossoverProbability")) {
192                     crossoverProbability =
193                             Double.parseDouble(new String(ch, start, length));
194                 } else if (currTag.equalsIgnoreCase("mutationOperator")) {
195                     mutationOperator =
196                             MutationOperatorType.valueOf(new String(ch, start,
197                                                                     length));
198                 } else if (currTag.equalsIgnoreCase("mutationProbability")) {
199                     mutationProbability =
200                             Double.parseDouble(new String(ch, start, length));
201                 } else if (currTag.equalsIgnoreCase("elitism")) {
202                     //Jeśli element ma wartość to nadpisz wartość wstawioną w startElement.elitism.
203                     elitism = Boolean.valueOf(new String(ch, start, length));
204                 } else if (currTag.equalsIgnoreCase("fitnessFunctionScript")) {
205                     fitnessFunctionScript = new String(ch, start, length);
206                 } else if (currTag.equalsIgnoreCase("fitnessFunctionOption")) {
207                     fitnessFunctionOption =
208                             FitnessFunctionOption.valueOf(new String(ch, start,
209                                                                      length));
210                 } else if (currTag.equalsIgnoreCase("initializePopulationConnectionName")) {
211                     this.initializePopulationConnectionName =
212                             new String(ch, start, length);
213                 } else if (currTag.equalsIgnoreCase("initializePopulationSQLQuery")) {
214                     this.initializePopulationSQLQuery =
215                             new String(ch, start, length);
216                 } else if (currTag.equalsIgnoreCase("populationSize")) {
217                     this.populationSize =
218                             Integer.parseInt(new String(ch, start, length));
219                 } else if (currTag.equalsIgnoreCase("maxGenerationCount")) {
220                     ga.setMaxGenerationCount(Integer.parseInt(new String(ch,
221                                                                          start,
222                                                                          length)));
223                 } else if (currTag.equalsIgnoreCase("lastGenerationTopChromosomeFind")) {
224                     ga.setLastGenerationTopChromosomeFind(Integer.parseInt(new String(ch,
225                                                                                       start,
226                                                                                       length)));
227                 }
228             }
229         };
230       
231         SchemaFactory schemaFactory = SchemaFactory
232                 .newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
233         SAXParserFactory factory = SAXParserFactory.newInstance();
234         factory.setValidating(false);//Wyłączenie walidacji (przestarzały mechanizm).
235         factory.setNamespaceAware(true); //Obsługa przestrzeni nazw.
236         try {
237             //Wymagana biblioteka xercesImpl.jar !!!!, zostala dodana w POM projektu.
238             InputStream xmlSchemaInputStream = GeneticAlgorithmXmlSaxParserFactory.class.getClassLoader().getResourceAsStream(XML_SCHEMA_FILE);
239             //InputStream xmlSchemaInputStream = this.getClass().getClassLoader().getResourceAsStream(XML_SCHEMA_FILE);
240             //InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(XML_SCHEMA_FILE);
241             factory.setSchema(schemaFactory.newSchema(new Source[]{new StreamSource(xmlSchemaInputStream)})); //Walidacja ze schematem
242             //factory.setSchema(schemaFactory.newSchema(new Source[]{new StreamSource("contacts.xsd")}));
243             //factory.setSchema(schemaFactory.newSchema(schemaFileUrl));
244             SAXParser saxParser = factory.newSAXParser();
245             XMLReader xmlReder = saxParser.getXMLReader(); //interfejs pozwala na analizę składni dokumentu xml
246             xmlReder.setContentHandler(handler);
247             xmlReder.setErrorHandler(new InitializeParametersXMLParserErrorHandler());
248             InputSource xmlInputSource = new InputSource(new java.io.ByteArrayInputStream(xmlParams.getBytes()));
249             xmlReder.parse(xmlInputSource);
250         } catch (ParserConfigurationException ex) {
251             Logger.getLogger(GeneticAlgorithmXmlSaxParserFactory.class.getName()).log(Level.SEVERE, null, ex);
252             throw new GeneticAlgorithmException(ex.getMessage());
253         } catch (SAXException ex) {
254             Logger.getLogger(GeneticAlgorithmXmlSaxParserFactory.class.getName()).log(Level.SEVERE, null, ex);
255             throw new GeneticAlgorithmException(ex.getMessage());
256         } catch (IOException ex) {
257             Logger.getLogger(GeneticAlgorithmXmlSaxParserFactory.class.getName()).log(Level.SEVERE, null, ex);
258             throw new GeneticAlgorithmException(ex.getMessage());
259         }
260       ga.setState(GeneticAlgorithmState.INITIALIZED);
261       return ga;
262     }
263 
264     private static class InitializeParametersXMLParserErrorHandler implements ErrorHandler {
265         @Override
266         public void warning(SAXParseException ex) throws SAXException {
267           System.out.println("CCC1"); 
268             Logger.getLogger(InitializeParametersXMLParserErrorHandler.class.getName()).log(Level.SEVERE, null, ex);
269             throw new SAXException(ex.getMessage());
270         }
271         @Override
272         public void error(SAXParseException ex) throws SAXException {
273           System.out.println("CCC2"); 
274             Logger.getLogger(InitializeParametersXMLParserErrorHandler.class.getName()).log(Level.SEVERE, null, ex);
275             throw new SAXException(ex.getMessage());
276         }
277         @Override
278         public void fatalError(SAXParseException ex) throws SAXException {
279           System.out.println("CCC3"); 
280             Logger.getLogger(InitializeParametersXMLParserErrorHandler.class.getName()).log(Level.SEVERE, null, ex);
281             throw new SAXException(ex.getMessage());
282         }
283     }
284 
285 }