root/tools/routingservice/branches/wrs-2.0/src/WRS.java @ 306

Revision 306, 19.2 KB (checked in by anton, 17 months ago)

Geometry transformation added

Line 
1/*  WRS 2.0
2 *  Copyright (C) 2009 Anton Patrushev
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18import handler.HandlerFactory;
19import handler.ResourceHandler;
20
21import java.io.IOException;
22import java.util.ArrayList;
23import java.util.Enumeration;
24import java.util.HashMap;
25import java.util.Hashtable;
26import java.util.Iterator;
27import java.util.ListIterator;
28import java.util.Vector;
29
30import javax.xml.bind.JAXBException;
31import javax.xml.parsers.ParserConfigurationException;
32
33import model.Profile;
34import model.Resource;
35import model.Service;
36import model.Template;
37
38import org.antlr.stringtemplate.StringTemplate;
39import org.geotools.referencing.CRS;
40import org.opengis.referencing.FactoryException;
41import org.opengis.referencing.NoSuchAuthorityCodeException;
42import org.opengis.referencing.crs.CoordinateReferenceSystem;
43import org.restlet.Component;
44import org.restlet.Restlet;
45import org.xml.sax.SAXException;
46
47import util.IOHelper;
48import util.Log;
49import util.ObjectPool;
50import util.Parameter;
51import util.ServiceRequest;
52import util.conf.Configuration;
53import util.conf.Configuration.Includes.Include;
54import util.format.FillerFactory;
55import util.format.FormatParser;
56import util.format.GMLTemplateFiller;
57import util.format.JSONParser;
58import util.format.ParserFactory;
59import util.format.TemplateFiller;
60import util.profile.Profiles;
61import util.profile.Profiles.Profile.Resources.Rref;
62import util.resource.Resources;
63import util.resource.Resources.Resource.Services;
64import util.Sref;
65
66import org.restlet.data.Form;
67import org.restlet.data.MediaType;
68import org.restlet.data.Method;
69import org.restlet.data.Protocol;
70import org.restlet.data.Request;
71import org.restlet.data.Response;
72import org.restlet.data.Status;
73
74import exception.InvalidProfileException;
75import exception.InvalidServiceException;
76import exception.InvalidTemplateException;
77import exception.InvalidVersionException;
78
79public class WRS
80{
81        private Log log;
82        private Configuration conf;
83
84        private Hashtable<String, Service> services;
85        private Hashtable<String, Profile> profiles;
86        private Hashtable<String, Resource> resources;
87
88        private static final String DEFAULT_VERSION = "1.1.0";
89
90        private enum Includes
91        {
92                TEMPLATES, SERVICES, PROFILES, RESOURCES;
93        }
94
95        private enum ParameterSources
96        {
97                URL, PROFILE, RESOURCE;
98        }
99
100        private enum MIMETypes
101        {
102                TEXT
103                {
104                        MediaType getType()
105                        {
106                                return MediaType.TEXT_ALL;
107                        }
108                },
109                JSON
110                {
111                        MediaType getType()
112                        {
113                                return MediaType.TEXT_JAVASCRIPT;
114                        }
115                },
116                HTML
117                {
118                        MediaType getType()
119                        {
120                                return MediaType.TEXT_HTML;
121                        }
122                },
123                XML
124                {
125                        MediaType getType()
126                        {
127                                return MediaType.TEXT_XML;
128                        }
129                };
130
131                abstract MediaType getType();
132
133        }
134
135        public WRS(String[] args) throws Exception
136        {
137                if (!checkParams(args))
138                {
139                        System.out.println("Wrong parameters");
140                        System.out.println("Usage: java WRS configuration.xml");
141                        System.exit(0);
142                }
143
144                this.resources = new Hashtable<String, Resource>();
145                this.services = new Hashtable<String, Service>();
146                this.profiles = new Hashtable<String, Profile>();
147
148                this.conf = readConfig(args[0]);
149
150                if (this.conf == null)
151                {
152                        System.out.println("Failed to configure service.");
153                        System.exit(0);
154                }
155
156                log = new Log(this.conf.getLog().getUrl(), this.conf.getLog()
157                                .getLevel().byteValue());
158                log.logger.info("Hello world!");
159
160                Component component = new Component();
161
162                log.logger.finest("Starting service at port " + this.conf.getPort());
163                component.getServers().add(Protocol.HTTP, this.conf.getPort());
164
165                Restlet restlet = new Restlet()
166                {
167
168                        synchronized public void handle(Request request, Response response)
169                        {
170                                log.logger.info("Handle request");
171                                ServiceRequest serviceRequest = null;
172                                String result = "";
173
174                                try
175                                {
176                                        serviceRequest = parseURL(request);
177
178                                        if (serviceRequest == null)
179                                                throw new ArrayIndexOutOfBoundsException();
180
181                                        Resource resource = serviceRequest.getResource();
182
183                                        if (resource == null)
184                                        {
185                                                // TODO process this case carefully
186                                        }
187                                        else
188                                        {
189                                                try
190                                                {
191                                                        ResourceHandler handler = HandlerFactory.Handler
192                                                                        .valueOf(resource.getType().toUpperCase())
193                                                                        .getInstance();
194                                                        handler.setResource(resource);
195
196                                                        ArrayList<HashMap<String, Parameter>> output = handler
197                                                                        .handle(serviceRequest, log);
198
199                                                        String templateName = serviceRequest.getTemplate()
200                                                                        .getName();
201
202                                                        try
203                                                        {
204                                                                TemplateFiller filler = FillerFactory.Fillers
205                                                                                .valueOf(templateName.toUpperCase())
206                                                                                .getInstance();
207                                                                result = filler.fillOutputTemplate(
208                                                                                serviceRequest, output, handler, log);
209                                                        }
210                                                        // TODO process the error more carefully
211                                                        catch (InstantiationException e)
212                                                        {
213                                                                log.logger.warning("Wrong output format "
214                                                                                + templateName);
215                                                        }
216                                                        catch (IllegalAccessException e)
217                                                        {
218                                                                log.logger.warning("Wrong output format "
219                                                                                + templateName);
220                                                        }
221                                                        catch (NullPointerException e)
222                                                        {
223                                                                log.logger.warning("Output format "
224                                                                                + templateName
225                                                                                + " is not supported yet.");
226                                                        }
227
228                                                }
229                                                // TODO process the error more carefully
230                                                catch (InstantiationException e)
231                                                {
232                                                        log.logger.warning("Wrong resource "
233                                                                        + resource.getName());
234                                                }
235                                                catch (IllegalAccessException e)
236                                                {
237                                                        log.logger.warning("Wrong resource "
238                                                                        + resource.getName());
239                                                }
240                                        }
241
242                                        String templateType = serviceRequest.getTemplate()
243                                                        .getFormat();
244                                        response.setEntity(result, MIMETypes.valueOf(
245                                                        templateType.toUpperCase()).getType());
246                                }
247                                catch (InvalidVersionException e)
248                                {
249                                        log.logger.warning("Invalid version '" + e.getVersion()
250                                                        + "'. Reqest can't be processed.");
251                                        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
252                                }
253                                catch (InvalidProfileException e)
254                                {
255                                        log.logger.warning("Invalid profile '" + e.getProfileName()
256                                                        + "'. Reqest can't be processed.");
257                                        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
258                                }
259                                catch (InvalidServiceException e)
260                                {
261                                        log.logger.warning("Invalid service '" + e.getServiceName()
262                                                        + "'. Reqest can't be processed.");
263                                        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
264                                }
265                                catch (InvalidTemplateException e)
266                                {
267                                        log.logger.warning("Invalid format '" + e.getTemplateName()
268                                                        + "'. Reqest can't be processed.");
269                                        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
270                                }
271                                catch (ArrayIndexOutOfBoundsException e)
272                                {
273                                        log.logger
274                                                        .warning("Invalid URL. Reqest can't be processed.");
275                                        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
276                                }
277                                catch (NullPointerException e)
278                                {
279                                        log.logger
280                                                        .warning("Invalid URL. Reqest can't be processed.");
281                                        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
282                                }
283
284                        }
285                };
286                component.getDefaultHost().attach("/{version}/{profile}/{service}",
287                                restlet);
288                component.start();
289
290        }
291
292        public ServiceRequest parseURL(Request req)
293                        throws ArrayIndexOutOfBoundsException, InvalidVersionException,
294                        InvalidProfileException, InvalidServiceException,
295                        InvalidTemplateException
296        {
297                // http://<servicedomain>:<port>/<version>/<profile>/<service>.<format>?<input>={<data>}
298
299                String cVersion = (String) req.getAttributes().get("version");
300
301                if (!this.conf.getVersion().equals(cVersion))
302                {
303                        throw new InvalidVersionException(cVersion);
304                }
305
306                String pName = (String) req.getAttributes().get("profile");
307                Profile cProfile = this.profiles.get(pName);
308
309                if (cProfile == null)
310                {
311                        throw new InvalidProfileException(pName);
312                }
313
314                String sName = ((String) req.getAttributes().get("service"))
315                                .split("\\.")[0];
316                ArrayList csList = (ArrayList) cProfile.getServices().get(sName);
317                // TODO implement a rule
318                Service cService = (Service) csList.get(0);
319
320                if (cService == null)
321                {
322                        throw new InvalidServiceException(sName);
323                }
324
325                String tName = ((String) req.getAttributes().get("service"))
326                                .split("\\.")[1];
327
328                Template cTemplate = cService.getTemplates().get(tName);
329
330                if (cTemplate == null)
331                {
332                        throw new InvalidTemplateException(tName);
333                }
334
335                ServiceRequest request = new ServiceRequest(cProfile, cService,
336                                cTemplate);
337
338                findResource(request);
339
340                // TODO parse and pass parameters
341
342                // Pass parameters from resource to service request
343                addParameters(request.getParameters(), request.getResource()
344                                .getParameters(), ParameterSources.RESOURCE.toString());
345
346                // Pass parameters from profile to service request
347                addParameters(request.getParameters(), cProfile.getParameters(),
348                                ParameterSources.PROFILE.toString());
349
350                Form form = new Form();
351                // GET Request
352                if (req.getMethod() == Method.GET)
353                {
354                        String paramString;
355                        try
356                        {
357                                paramString = req.getResourceRef().getRemainingPart().split(
358                                                "\\?")[1];
359                                form = new Form(paramString);
360                        }
361                        catch (ArrayIndexOutOfBoundsException e)
362                        {
363                                // No parameters. It might happen. Do nothing.
364                        }
365                }
366                // POST Request
367                else if (req.getMethod() == Method.POST)
368                {
369                        form = req.getEntityAsForm();
370                }
371                else
372                {
373                        log.logger.finest("Method " + req.getMethod()
374                                        + " is not supported yet.");
375                        return null;
376                }
377
378                Iterator<String> ni = form.getNames().iterator();
379                while (ni.hasNext())
380                {
381                        String inputFormat = ni.next();
382                        String inputBody = form.getValuesMap().get(inputFormat);
383
384                        try
385                        {
386                                FormatParser parser = ParserFactory.Formats.valueOf(
387                                                inputFormat.toUpperCase()).getInstance();
388                                HashMap<String, Parameter> params = parser.parse(inputBody);
389                                addParameters(request.getParameters(), params,
390                                                ParameterSources.URL.toString());
391                        }
392                        // TODO process the error more carefully
393                        catch (InstantiationException e)
394                        {
395                                log.logger.warning("Wrong format " + inputFormat);
396                        }
397                        catch (IllegalAccessException e)
398                        {
399                                log.logger.warning("Wrong format " + inputFormat);
400                        }
401                        catch (NullPointerException e)
402                        {
403                                log.logger.warning("Format " + inputFormat
404                                                + " is not supported yet.");
405                        }
406                }
407
408                return request;
409        }
410
411        private void addParameters(HashMap<String, Parameter> parameters,
412                        HashMap<String, Parameter> toAdd, String source)
413        {
414                // TODO check for ability to override parameters
415
416                Iterator<String> it = toAdd.keySet().iterator();
417                while (it.hasNext())
418                {
419                        Parameter p;
420                        String key = it.next();
421                        String value = toAdd.get(key).getValue();
422
423                        if (parameters.containsKey(key))
424                        {
425                                p = parameters.get(key);
426                               
427                                if (ParameterSources.valueOf(source).compareTo(
428                                                ParameterSources.valueOf(p.getSource()))<=0)
429                                {
430                                        //Override parameter value only if it is allowed
431                                        if(p.isConstant() == null || !p.isConstant())
432                                        {
433                                                p.setValue(value);
434                                                p.setSource(source);
435                                        }
436                                }
437                                else
438                                {
439                                        //Miracle happened and a parameter from upper level is already there
440                                        //Do nothing.
441                                        //Keep this case for the future needs.
442                                }
443                               
444                        }
445                        else
446                        {
447                                p = toAdd.get(key);
448                                p.setSource(source);
449                                parameters.put(key, p);
450                        }
451                }
452                // parameters.putAll(toAdd);
453        }
454
455        public static void main(String[] args)
456        {
457                try
458                {
459                        new WRS(args);
460                }
461                catch (Exception e)
462                {
463                        System.out.println("Error: Can't start the service.");
464                        e.printStackTrace();
465                }
466        }
467
468        public Configuration readConfig(String url)
469        {
470                Configuration conf = null;
471
472                try
473                {
474                        conf = IOHelper.readConfig(Configuration.class, url);
475
476                        ListIterator<Include> li = conf.getIncludes().getInclude()
477                                        .listIterator();
478
479                        while (li.hasNext())
480                        {
481                                Include inc = li.next();
482                               
483                                switch (Includes.valueOf(inc.getName().toUpperCase()))
484                                {
485                                case SERVICES:
486                                        readServices(inc.getUrl());
487                                        break;
488                                case PROFILES:
489                                        readProfiles(inc.getUrl());
490                                        break;
491                                case RESOURCES:
492                                        readResources(inc.getUrl());
493                                        break;
494                                }
495                        }
496
497                }
498                catch (SAXException e)
499                {
500                        System.out.println("Wrong configuration file.");
501                }
502                catch (IOException e)
503                {
504                        System.out.println("Can't open configuration file.");
505                }
506                catch (ParserConfigurationException e)
507                {
508                        System.out.println("Wrong configuration file.");
509                }
510                catch (JAXBException e)
511                {
512                        System.out.println("Wrong configuration file.");
513                }
514
515                return conf;
516        }
517       
518        private void readResources(String url)
519        {
520                System.out.println("Read resources from " + url + " file.");
521                Resources resources;
522                try
523                {
524                        resources = IOHelper.readConfig(Resources.class, url);
525                        ListIterator<util.resource.Resources.Resource> li = resources
526                                        .getResource().listIterator();
527                        while (li.hasNext())
528                        {
529                                util.resource.Resources.Resource res = li.next();
530                                Resource resource = new Resource(res.getName(), res.getType(),
531                                                res.getUrl(), res.getUser(), res.getPassword(), res
532                                                                .getQuery());
533
534                                ListIterator<Parameter> pi = res.getParameters().getParameter()
535                                                .listIterator();
536                                while (pi.hasNext())
537                                {
538                                        Parameter p = pi.next();
539                                        if (p.getSource() == null)
540                                                p.setSource("resource");
541                                        resource.getParameters().put(p.getName(), p);
542                                }
543
544                                ListIterator<Sref> si = res.getServices().getSref()
545                                                .listIterator();
546                                while (si.hasNext())
547                                {
548                                        Sref sref = si.next();
549                                        Service service = this.services.get(sref.getRef());
550                                        if (service != null)
551                                        {
552                                                resource.getServices().put(service.getName(), service);
553                                        }
554                                        else
555                                        {
556                                                System.out.println("No such service: " + sref.getRef());
557                                        }
558                                }
559
560                                this.resources.put(resource.getName(), resource);
561                        }
562
563                }
564                catch (SAXException e)
565                {
566                        System.out.println("Wrong resources configuration file.");
567                }
568                catch (IOException e)
569                {
570                        System.out.println("Can't open resources configuration file.");
571                }
572                catch (ParserConfigurationException e)
573                {
574                        System.out.println("Wrong resources configuration file.");
575                }
576                catch (JAXBException e)
577                {
578                        System.out.println("Wrong resources configuration file.");
579                }
580
581        }
582
583        private void readProfiles(String url)
584        {
585                System.out.println("Read profiles from " + url + " file.");
586                try
587                {
588                        Profiles profiles = IOHelper.readConfig(Profiles.class, url);
589                        ListIterator<util.profile.Profiles.Profile> li = profiles
590                                        .getProfile().listIterator();
591                        while (li.hasNext())
592                        {
593                                util.profile.Profiles.Profile prof = li.next();
594                                Profile profile = new Profile(prof.getName());
595                                profile.setDescription(prof.getDescription());
596                                ListIterator<Rref> ri = prof.getResources().getRref()
597                                                .listIterator();
598                                while (ri.hasNext())
599                                {
600                                        Rref rref = ri.next();
601
602                                        try
603                                        {
604                                                Resource res = this.resources.get(rref.getRef());
605                                                if (res != null)
606                                                {
607                                                        /*
608                                                         * Enumeration<String> pi =
609                                                         * res.getParameters().keys(); while
610                                                         * (pi.hasMoreElements()) { String pk =
611                                                         * pi.nextElement(); profile.getParameters().put(pk,
612                                                         * res.getParameters().get(pk)); }
613                                                         */
614                                                        Enumeration<String> si = res.getServices().keys();
615                                                        while (si.hasMoreElements())
616                                                        {
617                                                                String sk = si.nextElement();
618                                                                profile.getServices().put(sk,
619                                                                                res.getServices().get(sk));
620
621                                                        }
622
623                                                        profile.getResources().put(res.getName(), res);
624                                                }
625                                                else
626                                                {
627                                                        System.out.println("No such resource: "
628                                                                        + rref.getRef());
629                                                }
630                                        }
631                                        catch (NullPointerException e)
632                                        {
633                                                System.out.println("Resource " + rref.getRef()
634                                                                + " is not properly configured");
635                                        }
636
637                                }
638
639                                ListIterator<Parameter> pi = prof.getParameters()
640                                                .getParameter().listIterator();
641                                while (pi.hasNext())
642                                {
643                                        Parameter p = pi.next();
644                                        if (p.getSource() == null)
645                                                p.setSource("profile");
646                                        profile.getParameters().put(p.getName(), p);
647                                }
648
649                                this.profiles.put(profile.getName(), profile);
650
651                        }
652                }
653                catch (SAXException e)
654                {
655                        System.out.println("Wrong profiles configuration file.");
656                }
657                catch (NullPointerException e)
658                {
659                        System.out.println("Wrong profiles configuration file.");
660                }
661                catch (IOException e)
662                {
663                        System.out.println("Can't open profiles configuration file.");
664                }
665                catch (ParserConfigurationException e)
666                {
667                        System.out.println("Wrong profiles configuration file.");
668                }
669                catch (JAXBException e)
670                {
671                        System.out.println("Wrong profiles configuration file.");
672                }
673
674        }
675
676        private Template readTemplate(util.service.Template temp)
677        {
678                Template template = new Template(temp.getName(), temp.getFormat());
679
680                String body;
681                try
682                {
683                        body = IOHelper.readFile(temp.getUrl());
684                        template.setBody(body);
685                }
686                catch (IOException e)
687                {
688                        System.out
689                                        .println("Can't open template body file " + temp.getUrl());
690                }
691
692                return template;
693        }
694
695        private void readServices(String url)
696        {
697                try
698                {
699                        System.out.println("Read services from " + url + " file.");
700                        util.service.Services services = IOHelper.readConfig(
701                                        util.service.Services.class, url);
702                        ListIterator<util.service.Services.Service> li = services
703                                        .getService().listIterator();
704
705                        while (li.hasNext())
706                        {
707                                util.service.Services.Service serv = li.next();
708                                Service service = new Service(serv.getName());
709
710                                ListIterator<util.service.Template> tempi = serv.getTemplates()
711                                                .getTemplate().listIterator();
712                                while (tempi.hasNext())
713                                {
714                                        util.service.Template temp = tempi.next();
715                                        Template template = readTemplate(temp);
716                                        service.getTemplates().put(template.getName(), template);
717                                }
718
719                                ListIterator<Parameter> inpi = serv.getIn().getParameter()
720                                                .listIterator();
721                                while (inpi.hasNext())
722                                {
723                                        Parameter param = inpi.next();
724                                        service.getIn().put(param.getName(), param);
725                                }
726                                ListIterator<Parameter> outpi = serv.getOut().getParameter()
727                                                .listIterator();
728                                while (outpi.hasNext())
729                                {
730                                        Parameter param = outpi.next();
731                                        service.getOut().put(param.getName(), param);
732                                }
733
734                                this.services.put(service.getName(), service);
735                        }
736                }
737                catch (SAXException e)
738                {
739                        System.out.println("Wrong services configuration file.");
740                }
741                catch (NullPointerException e)
742                {
743                        System.out.println("Wrong services configuration file.");
744                }
745                catch (IOException e)
746                {
747                        System.out.println("Can't open services configuration file.");
748                }
749                catch (ParserConfigurationException e)
750                {
751                        System.out.println("Wrong services configuration file.");
752                }
753                catch (JAXBException e)
754                {
755                        System.out.println("Wrong services configuration file.");
756                }
757        }
758
759        private boolean checkParams(String args[])
760        {
761                boolean isOk = false;
762                if (args.length == 1)
763                        isOk = true;
764                return isOk;
765        }
766
767        private void findResource(ServiceRequest serviceRequest)
768        {
769                Resource resource = null;
770
771                Iterator<String> resKeys = serviceRequest.getProfile().getResources().keySet().iterator();
772                while (resKeys.hasNext())
773                {
774                        Resource res = serviceRequest.getProfile().getResources().get(
775                                        resKeys.next());
776
777                        // Take the first resource which has requested service
778                        // TODO There could be more sophisticated rule for choosing a
779                        // resource
780
781                        if (res.getServices().containsKey(
782                                        serviceRequest.getService().getName()))
783                        {
784                                resource = res;
785                                break;
786                        }
787                }
788
789                serviceRequest.setResource(resource);
790        }
791
792}
Note: See TracBrowser for help on using the browser.