EMMA Coverage Report (generated Sat Apr 14 15:01:05 EDT 2012)
[all classes][org.deduced.viewer.web.server]

COVERAGE SUMMARY FOR SOURCE FILE [DynamicUserInterfaceServiceImplementation.java]

nameclass, %method, %block, %line, %
DynamicUserInterfaceServiceImplementation.java83%  (5/6)88%  (43/49)57%  (797/1387)74%  (223.5/302)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DynamicUserInterfaceServiceImplementation$50%   (0/1)0%   (0/2)0%   (0/20)0%   (0/3)
DynamicUserInterfaceServiceImplementation$5 (DynamicUserInterfaceServiceImple... 0%   (0/1)0%   (0/12)0%   (0/1)
runAndThrow (): void 0%   (0/1)0%   (0/8)0%   (0/2)
     
class DynamicUserInterfaceServiceImplementation100% (1/1)90%  (35/39)55%  (706/1276)73%  (204.5/280)
getJarListFromFolder (String): String 0%   (0/1)0%   (0/12)0%   (0/4)
init (): void 0%   (0/1)0%   (0/5)0%   (0/3)
printStringList (List): String 0%   (0/1)0%   (0/38)0%   (0/9)
signalTriggered (String, String): void 0%   (0/1)0%   (0/152)0%   (0/18)
updateProperty (String, String, SerializedValue): void 100% (1/1)30%  (29/96)73%  (8/11)
loadConfiguration (): void 100% (1/1)31%  (13/42)38%  (4.5/12)
updateReferenceList (String, ArrayList): void 100% (1/1)33%  (28/86)73%  (8/11)
configureCompilerArguments (): void 100% (1/1)35%  (18/51)50%  (6/12)
getInitialUserInterface (): ViewModel 100% (1/1)44%  (24/54)54%  (7/13)
configureOpenFileName (String): void 100% (1/1)47%  (15/32)83%  (5/6)
getChangeEventList (): ArrayList 100% (1/1)48%  (37/77)65%  (11/17)
configureWebViewName (String): void 100% (1/1)65%  (24/37)86%  (6/7)
configureDynamicCodeGenerationFolder (String): void 100% (1/1)67%  (34/51)89%  (8/9)
configureDynamicCodeLibraryFolder (String): void 100% (1/1)67%  (34/51)89%  (8/9)
runUpdateProperty (String, String, SerializedValue): void 100% (1/1)70%  (74/106)90%  (19/21)
isDeducedFoundInSystemClassLoader (): boolean 100% (1/1)76%  (16/21)75%  (6/8)
resolvePathRelativeToFileSystemOrWar (String): String 100% (1/1)90%  (19/21)88%  (7/8)
createWebViewLayer (): void 100% (1/1)91%  (32/35)86%  (6/7)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
DynamicUserInterfaceServiceImplementation (): void 100% (1/1)100% (33/33)100% (10/10)
configureDynamicCodeOutputFolderName (): void 100% (1/1)100% (4/4)100% (2/2)
configureRuleExecutionClassLoader (): void 100% (1/1)100% (10/10)100% (3/3)
configureTemporaryRuleFiles (): void 100% (1/1)100% (7/7)100% (4/4)
convertStringToObjectID (String): Long 100% (1/1)100% (3/3)100% (1/1)
convertToSerializableException (Exception): Exception 100% (1/1)100% (6/6)100% (1/1)
getApplication (): StartLiveApplication 100% (1/1)100% (3/3)100% (1/1)
getCollectionFromStingID (String): PropertyCollection 100% (1/1)100% (16/16)100% (7/7)
getOpenFileName (): String 100% (1/1)100% (3/3)100% (1/1)
getPropertyCollectionIndex (): PropertyCollectionIndex 100% (1/1)100% (3/3)100% (1/1)
getPropertyEntryByName (String, PropertyCollection): Map$Entry 100% (1/1)100% (36/36)100% (11/11)
initialize (): void 100% (1/1)100% (15/15)100% (8/8)
initializeDeducedApplication (): void 100% (1/1)100% (8/8)100% (2/2)
initializeInfrastructure (): void 100% (1/1)100% (16/16)100% (4/4)
runUpdateReferenceList (String, List): void 100% (1/1)100% (77/77)100% (17/17)
setApplication (StartLiveApplication): void 100% (1/1)100% (4/4)100% (2/2)
setConfiguredValues (Properties): void 100% (1/1)100% (33/33)100% (9/9)
setOpenFileName (String): void 100% (1/1)100% (4/4)100% (2/2)
setUiRoot (PropertyCollection): void 100% (1/1)100% (11/11)100% (4/4)
stop (): void 100% (1/1)100% (12/12)100% (4/4)
     
class DynamicUserInterfaceServiceImplementation$1100% (1/1)100% (2/2)100% (12/12)100% (2/2)
DynamicUserInterfaceServiceImplementation$1 (DynamicUserInterfaceServiceImple... 100% (1/1)100% (6/6)100% (1/1)
run (): AbstractDynamicExecutionCompiler$LocalClassLoader 100% (1/1)100% (6/6)100% (1/1)
     
class DynamicUserInterfaceServiceImplementation$2100% (1/1)100% (2/2)100% (34/34)100% (11/11)
DynamicUserInterfaceServiceImplementation$2 (DynamicUserInterfaceServiceImple... 100% (1/1)100% (6/6)100% (1/1)
run (): void 100% (1/1)100% (28/28)100% (10/10)
     
class DynamicUserInterfaceServiceImplementation$3100% (1/1)100% (2/2)100% (25/25)100% (3/3)
DynamicUserInterfaceServiceImplementation$3 (DynamicUserInterfaceServiceImple... 100% (1/1)100% (15/15)100% (1/1)
runAndThrow (): void 100% (1/1)100% (10/10)100% (2/2)
     
class DynamicUserInterfaceServiceImplementation$4100% (1/1)100% (2/2)100% (20/20)100% (3/3)
DynamicUserInterfaceServiceImplementation$4 (DynamicUserInterfaceServiceImple... 100% (1/1)100% (12/12)100% (1/1)
runAndThrow (): void 100% (1/1)100% (8/8)100% (2/2)

1/**
2 *    Copyright 2005-2011 Steve McDuff d-duff@users.sourceforge.net
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.deduced.viewer.web.server;
17 
18import java.io.File;
19import java.io.FileInputStream;
20import java.io.Serializable;
21import java.security.AccessController;
22import java.security.PrivilegedAction;
23import java.util.ArrayList;
24import java.util.List;
25import java.util.Map.Entry;
26import java.util.Properties;
27import java.util.Set;
28import java.util.logging.Level;
29import java.util.logging.Logger;
30 
31import javax.servlet.ServletContext;
32import javax.servlet.ServletException;
33 
34import org.apache.commons.io.IOUtils;
35import org.apache.commons.lang.ObjectUtils;
36import org.deduced.DeducedModelLayerExtension;
37import org.deduced.DeducedUtilities;
38import org.deduced.ModelFactory;
39import org.deduced.Property;
40import org.deduced.PropertyCollection;
41import org.deduced.dynamic.AbstractDynamicExecutionCompiler;
42import org.deduced.dynamic.AbstractDynamicExecutionCompiler.LocalClassLoader;
43import org.deduced.framework.ControllerSchema;
44import org.deduced.framework.FrameworkLoader;
45import org.deduced.implementation.PropertyInstanceImplementation;
46import org.deduced.live.StartLiveApplication;
47import org.deduced.rule.DeductionRuleLibrary;
48import org.deduced.utilities.AssertUtilities;
49import org.deduced.utilities.ExceptionRunnable;
50import org.deduced.utilities.FileUtilities;
51import org.deduced.utilities.ObjectUtilities;
52import org.deduced.utilities.Runner;
53import org.deduced.utilities.SwingInvokeAndWaitRunner;
54import org.deduced.validation.ValidationUtilities;
55import org.deduced.viewer.framework.DeducedViewLayerExtensionImplementation;
56import org.deduced.viewer.framework.ViewSchema;
57import org.deduced.viewer.web.serializer.MasterWebSerializer;
58import org.deduced.viewer.web.serializer.MasterWebSerializerImplementation;
59import org.deduced.viewer.web.shared.ChangeEvent;
60import org.deduced.viewer.web.shared.DynamicUserInterfaceService;
61import org.deduced.viewer.web.shared.SerializedValue;
62import org.deduced.viewer.web.shared.ViewModel;
63 
64import com.google.gwt.user.server.rpc.RemoteServiceServlet;
65 
66/**
67 * DynamicUserInterfaceServiceImplementation is the main remote service servlet
68 * that will start the deduced application and offer the services used to
69 * interact with a client.
70 * 
71 * @author Steve McDuff
72 * 
73 */
74public class DynamicUserInterfaceServiceImplementation extends
75        RemoteServiceServlet implements DynamicUserInterfaceService
76{
77 
78        /**
79         * serialVersionUID
80         */
81        private static final long serialVersionUID = -3456009224256315787L;
82 
83        /**
84         * logger
85         */
86        private static final Logger LOGGER = Logger
87                .getLogger(DynamicUserInterfaceServiceImplementation.class.getName());
88 
89        /**
90         * application file property name
91         */
92        public static final String DEDUCED_APPLICATION_FILE =
93                "deduced.application.file";
94 
95        /**
96         * dynamic code generation folder property name
97         */
98        public static final String DEDUCED_DYNAMIC_CODE_GENERATION_FOLDER =
99                "deduced.dynamic.code.generation.folder";
100 
101        /**
102         * dynamic code library folder property name
103         */
104        public static final String DEDUCED_DYNAMIC_CODE_LIBRARY_FOLDER =
105                "deduced.dynamic.code.library.folder";
106 
107        /**
108         * name of the web view object
109         */
110        public static final String DEDUCED_WEB_VIEW_NAME = "deduced.web.view.name";
111 
112        /**
113         * deduced live application
114         */
115        private StartLiveApplication application;
116 
117        /**
118         * user interface root collection
119         */
120        private PropertyCollection uiRoot;
121 
122        /**
123         * deduced application request runner to ensure that requests are done in
124         * the right thread.
125         */
126        private Runner requestRunner = new SwingInvokeAndWaitRunner();
127 
128        /**
129         * property collection index that references all UI collections and monitors
130         * their change events.
131         */
132        private PropertyCollectionIndex listener = new PropertyCollectionIndex();
133 
134        /**
135         * change event aggregator to accumulate change events and send them to the
136         * client
137         */
138        private SerializedChangeEventAggregator aggregator =
139                new SerializedChangeEventAggregator();
140 
141        /**
142         * implementation of the serializer used to send the final version to the
143         * client
144         */
145        private MasterWebSerializer serializer = null;
146 
147        /**
148         * web view layer
149         */
150        private DeducedModelLayerExtension viewLayer;
151 
152        /**
153         * file to open when starting the application
154         */
155        private String openFileName = null;
156 
157        /**
158         * folder name where the dynamic code is generated
159         */
160        private String dynamicCodeGenerationFolder = null;
161 
162        /**
163         * folder name where the dynamic code libraries are located
164         */
165        private String dynamicCodeLibraryFolder = null;
166 
167        /**
168         * web view object name
169         */
170        private String webViewObjectName = null;
171 
172        /**
173         * 
174         * DynamicUserInterfaceServiceImplementation constructor
175         */
176        public DynamicUserInterfaceServiceImplementation()
177        {
178 
179        }
180 
181        /**
182         * (non-JSDoc)
183         * 
184         * @see javax.servlet.GenericServlet#init()
185         */
186        @Override
187        public void init() throws ServletException
188        {
189                super.init();
190 
191                initialize();
192        }
193 
194        /**
195         * initialize
196         */
197        protected void initialize()
198        {
199                loadConfiguration();
200 
201                configureTemporaryRuleFiles();
202 
203                configureRuleExecutionClassLoader();
204 
205                configureCompilerArguments();
206 
207                configureDynamicCodeOutputFolderName();
208 
209                initializeDeducedApplication();
210 
211                initializeInfrastructure();
212        }
213 
214        /**
215         * set all Configured Values
216         * 
217         * @param deducedProperties the properties used to start the application
218         */
219        private void setConfiguredValues(
220                Properties deducedProperties)
221        {
222                String configuredOpenFileName =
223                        (String) deducedProperties.get(DEDUCED_APPLICATION_FILE);
224 
225                configureOpenFileName(configuredOpenFileName);
226 
227                String configuredDynamicCodeGenerationFolder =
228                        (String) deducedProperties
229                                .get(DEDUCED_DYNAMIC_CODE_GENERATION_FOLDER);
230 
231                configureDynamicCodeGenerationFolder(configuredDynamicCodeGenerationFolder);
232 
233                String configuredDynamicCodeLibraryFolder =
234                        (String) deducedProperties.get(DEDUCED_DYNAMIC_CODE_LIBRARY_FOLDER);
235 
236                configureDynamicCodeLibraryFolder(configuredDynamicCodeLibraryFolder);
237 
238                String configuredWebViewName =
239                        (String) deducedProperties.get(DEDUCED_WEB_VIEW_NAME);
240 
241                configureWebViewName(configuredWebViewName);
242        }
243 
244        /**
245         * configure Web View Name
246         * 
247         * @param configuredWebViewName the configured value
248         */
249        private void configureWebViewName(
250                String configuredWebViewName)
251        {
252                String finalName = configuredWebViewName;
253                if (configuredWebViewName == null)
254                {
255                        finalName = "web view";
256 
257                        LOGGER.log(Level.INFO, "No value specified in \""
258                                + DEDUCED_WEB_VIEW_NAME + "\". Using default value of : \""
259                                + finalName + "\".");
260 
261                }
262                else
263                {
264                        LOGGER.log(Level.INFO, "Configured value \""
265                                + DEDUCED_WEB_VIEW_NAME + "\" set to \"" + finalName + "\".");
266                }
267                webViewObjectName = finalName;
268        }
269 
270        /**
271         * configure Dynamic Code Generation Folder
272         * 
273         * @param configuredDynamicCodeGenerationFolder the configured value
274         */
275        private void configureDynamicCodeGenerationFolder(
276                String configuredDynamicCodeGenerationFolder)
277        {
278                String pathWithDefault = configuredDynamicCodeGenerationFolder;
279                if (pathWithDefault == null)
280                {
281                        pathWithDefault = "WEB-INF/deduced/generated";
282                }
283 
284                String resolvedPath =
285                        resolvePathRelativeToFileSystemOrWar(pathWithDefault);
286 
287                dynamicCodeGenerationFolder = resolvedPath;
288 
289                if (configuredDynamicCodeGenerationFolder == null)
290                {
291                        LOGGER.log(Level.INFO, "No value specified in \""
292                                + DEDUCED_DYNAMIC_CODE_GENERATION_FOLDER
293                                + "\". Using default value of \"" + pathWithDefault
294                                + "\". Generating dynamic code in folder \"" + resolvedPath
295                                + "\".");
296                }
297                else
298                {
299                        LOGGER.log(Level.INFO, "Configured value \""
300                                + DEDUCED_DYNAMIC_CODE_GENERATION_FOLDER + "\" set to \""
301                                + configuredDynamicCodeGenerationFolder
302                                + "\". Generating dynamic code in folder \"" + resolvedPath
303                                + "\".");
304                }
305        }
306 
307        /**
308         * configure Dynamic Code Library Folder
309         * 
310         * @param configuredDynamicCodeLibraryFolder the configured value
311         */
312        private void configureDynamicCodeLibraryFolder(
313                String configuredDynamicCodeLibraryFolder)
314        {
315                String pathWithDefault = configuredDynamicCodeLibraryFolder;
316                if (pathWithDefault == null)
317                {
318                        pathWithDefault = "WEB-INF/lib";
319                }
320 
321                String resolvedPath =
322                        resolvePathRelativeToFileSystemOrWar(pathWithDefault);
323 
324                dynamicCodeLibraryFolder = resolvedPath;
325 
326                if (configuredDynamicCodeLibraryFolder == null)
327                {
328                        LOGGER.log(Level.INFO, "No value specified in \""
329                                + DEDUCED_DYNAMIC_CODE_LIBRARY_FOLDER
330                                + "\". Using default value of \"" + pathWithDefault
331                                + "\". Dynamic code library folder resolved to \""
332                                + resolvedPath + "\".");
333                }
334                else
335                {
336                        LOGGER.log(Level.INFO, "Configured value \""
337                                + DEDUCED_DYNAMIC_CODE_LIBRARY_FOLDER + "\" set to \""
338                                + configuredDynamicCodeLibraryFolder
339                                + "\". Dynamic code library folder resolved to \""
340                                + resolvedPath + "\".");
341                }
342        }
343 
344        /**
345         * configure the Open File Name by looking on the system and on the WAR for
346         * the specified name
347         * 
348         * @param configuredOpenFileName the configured file name
349         */
350        private void configureOpenFileName(
351                String configuredOpenFileName)
352        {
353                String resolvedPath =
354                        resolvePathRelativeToFileSystemOrWar(configuredOpenFileName);
355 
356                setOpenFileName(resolvedPath);
357 
358                if (resolvedPath == null)
359                {
360                        LOGGER.log(Level.INFO, "No file specified in \""
361                                + DEDUCED_APPLICATION_FILE + "\". Starting a new application.");
362                }
363                else
364                {
365                        LOGGER.log(Level.INFO, "Configured value \""
366                                + DEDUCED_APPLICATION_FILE + "\" set to \""
367                                + configuredOpenFileName
368                                + "\". Initializing the application using \"" + resolvedPath
369                                + "\".");
370                }
371        }
372 
373        /**
374         * resolve a Path Relative To the File System Or War file folder. If the
375         * configured path starts with the "WEB-INF" prefix, then a relative path to
376         * the WAR file is used.
377         * 
378         * @param configuredPath the configured path
379         * @return the resolved system file path
380         */
381        public String resolvePathRelativeToFileSystemOrWar(
382                String configuredPath)
383        {
384                String resolvedPath = null;
385                if (configuredPath != null)
386                {
387                        if (configuredPath.toLowerCase().startsWith("web-inf"))
388                        {
389                                // file not found on file system, reverting to WAR relative path
390                                ServletContext servletContext = getServletContext();
391 
392                                resolvedPath = servletContext.getRealPath(configuredPath);
393                        }
394                        else
395                        {
396                                resolvedPath = configuredPath;
397                        }
398                }
399                return resolvedPath;
400        }
401 
402        /**
403         * load Configuration
404         */
405        private void loadConfiguration()
406        {
407                ServletContext servletContext = getServletContext();
408 
409                Properties deducedProperties = new Properties();
410 
411                String deducedPropertiesFilePath =
412                        servletContext.getRealPath("WEB-INF/deduced/deduced.properties");
413 
414                FileInputStream fis = null;
415                try
416                {
417                        fis = new FileInputStream(deducedPropertiesFilePath);
418                        deducedProperties.load(fis);
419                }
420                catch (Exception e)
421                {
422                        LOGGER.log(Level.WARNING,
423                                "Failed to load the deduced web application configuration files."
424                                        + " Using default values.", e);
425                }
426                finally
427                {
428                        IOUtils.closeQuietly(fis);
429                }
430 
431                setConfiguredValues(deducedProperties);
432        }
433 
434        /**
435         * configure Dynamic Code Output Folder Name to use the WEB-INF folder to
436         * ensure we don't expose generated code
437         */
438        private void configureDynamicCodeOutputFolderName()
439        {
440                AbstractDynamicExecutionCompiler
441                        .setOutputFolderName(dynamicCodeGenerationFolder);
442        }
443 
444        /**
445         * 
446         * initializeInfrastructure
447         */
448        protected void initializeInfrastructure()
449        {
450                serializer = new MasterWebSerializerImplementation();
451                aggregator.setSerializer(serializer);
452                listener.setLinkedListener(aggregator);
453        }
454 
455        /**
456         * get Open File Name
457         * 
458         * @return the open file name
459         */
460        public String getOpenFileName()
461        {
462                return openFileName;
463        }
464 
465        /**
466         * set Open File Name
467         * 
468         * @param newOpenFileName the file name to open
469         */
470        public void setOpenFileName(
471                String newOpenFileName)
472        {
473                openFileName = newOpenFileName;
474        }
475 
476        /**
477         * configure the Rule Execution Class Loader to use right web application
478         * class loader
479         */
480        private void configureRuleExecutionClassLoader()
481        {
482                LocalClassLoader newLoader =
483                        AccessController
484                                .doPrivileged(new PrivilegedAction<LocalClassLoader>()
485                                {
486                                        @Override
487                                        public LocalClassLoader run()
488                                        {
489                                                return new LocalClassLoader(Thread.currentThread()
490                                                        .getContextClassLoader());
491                                        }
492                                });
493                AbstractDynamicExecutionCompiler.setDynamicClassLoader(newLoader);
494        }
495 
496        /**
497         * configure the Compiler Arguments to be passed during dynamic code
498         * compilation so that we may find the required JARs.
499         */
500        private void configureCompilerArguments()
501        {
502                List<String> argumentList = new ArrayList<String>();
503 
504                boolean isDeducedFoundInSystemClassLoader =
505                        isDeducedFoundInSystemClassLoader();
506 
507                if (isDeducedFoundInSystemClassLoader)
508                {
509                        LOGGER.log(Level.INFO,
510                                "The deduced framework classes are present in the system classpath."
511                                        + " Ignoring the configured library folder.");
512                }
513                else
514                {
515                        String compilationJarList =
516                                getJarListFromFolder(dynamicCodeLibraryFolder);
517 
518                        argumentList.add("-cp");
519                        argumentList.add(compilationJarList);
520 
521                        LOGGER.log(Level.INFO,
522                                "The dynamic code compiler will use the following"
523                                        + " path to find the deduced framework classes : "
524                                        + compilationJarList);
525                }
526 
527                if (argumentList.size() > 0)
528                {
529                        String[] argumentArray =
530                                argumentList.toArray(new String[argumentList.size()]);
531                        AbstractDynamicExecutionCompiler
532                                .setCompilerArguments(argumentArray);
533                }
534        }
535 
536        /**
537         * get Jar List From Folder and return it as a classpath
538         * 
539         * @param libraryFolderName the folder name to scan
540         * @return the list of jars in a comma separated list.
541         */
542        private String getJarListFromFolder(
543                String libraryFolderName)
544        {
545                File[] jarListFromFolder =
546                        FileUtilities.getJarListFromFolder(libraryFolderName);
547 
548                List<String> canonicalFilePathList =
549                        FileUtilities.getCanonicalFilePathList(jarListFromFolder);
550 
551                String returnValue =
552                        ObjectUtilities.aggregateStringListWithSeparator(
553                                canonicalFilePathList, File.pathSeparator);
554 
555                return returnValue;
556        }
557 
558        /**
559         * check if Deduced classes are Found In the System Class Loader
560         * 
561         * @return true if the system class loader has access to the deduced
562         *         libraries
563         */
564        protected boolean isDeducedFoundInSystemClassLoader()
565        {
566                boolean isDeducedFoundInSystemClassLoader = false;
567 
568                try
569                {
570                        ClassLoader.getSystemClassLoader().loadClass(
571                                DeductionRuleLibrary.class.getName());
572                        isDeducedFoundInSystemClassLoader = true;
573 
574                        LOGGER
575                                .log(Level.FINE,
576                                        "The deduced framework classes were found in the system class loader.");
577                }
578                catch (ClassNotFoundException e)
579                {
580                        LOGGER
581                                .log(Level.FINE,
582                                        "The deduced framework classes weren't found in the system class loader.");
583                }
584                return isDeducedFoundInSystemClassLoader;
585        }
586 
587        /**
588         * initialize Deduced Application
589         */
590        protected void initializeDeducedApplication()
591        {
592                requestRunner.runSilent(new Runnable()
593                {
594                        @Override
595                        public void run()
596                        {
597                                FrameworkLoader.createBaseSchema();
598                                ViewSchema.initializeFromXml();
599                                ControllerSchema.initializeFromXml();
600 
601                                StartLiveApplication newApplication =
602                                        new StartLiveApplication(null);
603                                setApplication(newApplication);
604 
605                                String currentOpenFileName = getOpenFileName();
606                                newApplication.startUserApplication(currentOpenFileName);
607                                newApplication.startDevelopmentApplication();
608 
609                                createWebViewLayer();
610                        }
611                });
612        }
613 
614        /**
615         * set Application
616         * 
617         * @param newApplication the new application
618         */
619        protected void setApplication(
620                StartLiveApplication newApplication)
621        {
622                application = newApplication;
623        }
624 
625        /**
626         * stop the user application
627         */
628        public void stop()
629        {
630                if (application != null)
631                {
632                        application.getDevelopmentApplication().stop();
633                        application.getUserApplication().stop();
634                }
635        }
636 
637        /**
638         * get the live application
639         * 
640         * @return the live application.
641         */
642        public StartLiveApplication getApplication()
643        {
644                return application;
645        }
646 
647        /**
648         * create the Web View Layer
649         */
650        protected void createWebViewLayer()
651        {
652                DeducedViewLayerExtensionImplementation applicationView =
653                        application.getUserApplication().getApplicationView();
654 
655                viewLayer = applicationView;
656 
657                PropertyCollection<?, ?> webView =
658                        DeducedUtilities.findChildByName(
659                                applicationView.getCollectionList(), webViewObjectName);
660 
661                if (webView == null)
662                {
663                        LOGGER
664                                .log(
665                                        Level.SEVERE,
666                                        "Failed to find the web view named \""
667                                                + webViewObjectName
668                                                + "\" located under the view layer. No web view will be available.");
669                }
670                else
671                {
672                        setUiRoot(webView);
673                }
674        }
675 
676        /**
677         * set the user interface root
678         * 
679         * @param webView the root view
680         */
681        public void setUiRoot(
682                PropertyCollection<?, ?> webView)
683        {
684                if (webView != null)
685                {
686                        uiRoot = webView;
687                        listener.setModel(uiRoot);
688                }
689        }
690 
691        /**
692         * get Property Collection Index
693         * 
694         * @return the property collection index
695         */
696        public PropertyCollectionIndex getPropertyCollectionIndex()
697        {
698                return listener;
699        }
700 
701        /**
702         * configure Temporary Rule Files
703         */
704        public void configureTemporaryRuleFiles()
705        {
706                AbstractDynamicExecutionCompiler
707                        .setAutomaticallyDeletingGeneratedJavaFiles(false);
708                AbstractDynamicExecutionCompiler
709                        .setAutomaticallyDeletingGeneratedClassFiles(false);
710                AbstractDynamicExecutionCompiler
711                        .setAutomaticallyDeletingGeneratedJavaFilesIfCompileFails(false);
712        }
713 
714        /**
715         * (non-JSDoc)
716         * 
717         * @see org.deduced.viewer.web.shared.DynamicUserInterfaceService#getInitialUserInterface()
718         */
719        @Override
720        public ViewModel getInitialUserInterface() throws Exception
721        {
722                if (LOGGER.isLoggable(Level.FINE))
723                {
724                        LOGGER.log(Level.FINE, "getInitialUserInterface entry.");
725                }
726 
727                ViewModel serializeModel = null;
728                try
729                {
730                        serializeModel = (ViewModel) serializer.serialize(uiRoot);
731                        aggregator.getChangeEventList().clear();
732                }
733                catch (Exception e)
734                {
735                        if (LOGGER.isLoggable(Level.SEVERE))
736                        {
737                                LOGGER.log(Level.SEVERE,
738                                        "getInitialUserInterface exit failed : " + e.getMessage(),
739                                        e);
740                        }
741 
742                        throw convertToSerializableException(e);
743                }
744 
745                if (LOGGER.isLoggable(Level.FINE))
746                {
747                        LOGGER.log(Level.FINE, "getInitialUserInterface exit success.");
748                }
749 
750                return serializeModel;
751        }
752 
753        /**
754         * (non-JSDoc)
755         * 
756         * @see org.deduced.viewer.web.shared.DynamicUserInterfaceService#getChangeEventList()
757         */
758        @Override
759        public ArrayList<ChangeEvent> getChangeEventList() throws Exception
760        {
761                if (LOGGER.isLoggable(Level.FINEST))
762                {
763                        LOGGER.log(Level.FINEST, "getChangeEventList entry.");
764                }
765 
766                ArrayList<ChangeEvent> retVal = new ArrayList<ChangeEvent>();
767 
768                try
769                {
770                        List<ChangeEvent> changeEventList = aggregator.getChangeEventList();
771 
772                        if (changeEventList.size() > 0)
773                        {
774                                ChangeEvent remove = null;
775 
776                                while (changeEventList.size() > 0)
777                                {
778                                        remove = changeEventList.remove(0);
779                                        retVal.add(remove);
780                                }
781                        }
782                }
783                catch (Exception ex)
784                {
785                        if (LOGGER.isLoggable(Level.SEVERE))
786                        {
787                                LOGGER.log(Level.FINE,
788                                        "getChangeEventList exit failed. " + ex.getMessage(), ex);
789                        }
790 
791                        throw convertToSerializableException(ex);
792                }
793 
794                if (LOGGER.isLoggable(Level.FINEST))
795                {
796                        LOGGER.log(Level.FINEST, "getChangeEventList exit. Returned "
797                                + retVal.size() + " events.");
798                }
799 
800                return retVal;
801        }
802 
803        /**
804         * (non-JSDoc)
805         * 
806         * @see org.deduced.viewer.web.shared.DynamicUserInterfaceService#updateProperty(java.lang.String,
807         *      java.lang.String, org.deduced.viewer.web.shared.SerializedValue)
808         */
809        @Override
810        public void updateProperty(
811                final String objectID, final String propertyName,
812                final SerializedValue newValue) throws Exception
813        {
814                if (LOGGER.isLoggable(Level.FINE))
815                {
816                        LOGGER.log(Level.FINE, "updateProperty entry : collection ID : \""
817                                + objectID + "\" property name : \"" + propertyName
818                                + "\" new value : \"" + newValue + "\". ");
819                }
820 
821                try
822                {
823                        requestRunner.run(new ExceptionRunnable()
824                        {
825                                @Override
826                                public void runAndThrow() throws Exception
827                                {
828                                        runUpdateProperty(objectID, propertyName, newValue);
829                                }
830                        });
831                }
832                catch (Exception e)
833                {
834                        if (LOGGER.isLoggable(Level.FINE))
835                        {
836                                LOGGER.log(
837                                        Level.FINE,
838                                        "updateProperty exit failed : collection ID : \""
839                                                + objectID + "\" property name : \"" + propertyName
840                                                + "\" new value : \"" + newValue + "\". "
841                                                + e.getMessage(), e);
842                        }
843                        throw convertToSerializableException(e);
844                }
845 
846                if (LOGGER.isLoggable(Level.FINE))
847                {
848                        LOGGER.log(Level.FINE,
849                                "updateProperty exit success : collection ID : \"" + objectID
850                                        + "\" property name : \"" + propertyName
851                                        + "\" new value : \"" + newValue + "\". ");
852                }
853 
854        }
855 
856        /**
857         * run Update Property
858         * 
859         * @param objectID the object ID to update
860         * @param propertyName the name of the property to update
861         * @param newValue the new value
862         * @throws Exception any error encountered while performing the update
863         */
864        @SuppressWarnings("unchecked")
865        protected void runUpdateProperty(
866                String objectID, String propertyName, SerializedValue newValue)
867                throws Exception
868        {
869                try
870                {
871                        Serializable serializedValue = newValue.getValue();
872                        PropertyCollection collection = getCollectionFromStingID(objectID);
873 
874                        if (collection == null)
875                        {
876                                throw new IllegalArgumentException(
877                                        "Unable to find collection of ID : \"" + objectID
878                                                + "\", for which to update : \"" + propertyName
879                                                + "\" to value \"" + serializedValue + "\".");
880                        }
881                        Entry<?, ? extends Property<?>> entry =
882                                getPropertyEntryByName(propertyName, collection);
883 
884                        if (entry == null)
885                        {
886                                throw new IllegalArgumentException(
887                                        "Unable to find the property :\"" + propertyName
888                                                + "\" on collection of ID : \"" + objectID
889                                                + "\", named  \""
890                                                + DeducedUtilities.getCollectionName(collection)
891                                                + "\", on which to set value \"" + serializedValue
892                                                + "\".");
893                        }
894 
895                        ModelFactory modelFactory = viewLayer.getModelFactory();
896                        Property<?> value = entry.getValue();
897                        PropertyCollection<?, ?> instance = value.getInstance();
898 
899                        Object setValue = serializedValue;
900 
901                        if (PropertyInstanceImplementation.isReference(instance)
902                                .booleanValue())
903                        {
904                                setValue = getCollectionFromStingID((String) serializedValue);
905                        }
906 
907                        ValidationUtilities.validateNewValueOnInstance(setValue,
908                                modelFactory, instance, true);
909 
910                        Object key = entry.getKey();
911                        collection.setProperty(key, setValue);
912 
913                }
914                catch (Exception e)
915                {
916                        AssertUtilities.exception(e);
917                        throw e;
918                }
919        }
920 
921        /**
922         * get a Property Entry By Name
923         * 
924         * @param propertyName name of the property
925         * @param collection collection from which to fetch the property entry
926         * @return the matching property entry
927         */
928        public static Entry<?, ? extends Property<?>> getPropertyEntryByName(
929                String propertyName, PropertyCollection<?, ?> collection)
930        {
931                Entry<?, ? extends Property<?>> retVal = null;
932 
933                if (collection != null)
934                {
935                        Set<? extends Entry<?, ? extends Property<?>>> asPropertyList =
936                                collection.asPropertyMap().entrySet();
937                        for (Entry<?, ? extends Property<?>> entry : asPropertyList)
938                        {
939                                PropertyCollection<?, ?> instance =
940                                        entry.getValue().getInstance();
941                                String instanceName =
942                                        DeducedUtilities.getCollectionName(instance);
943                                if (ObjectUtils.equals(propertyName, instanceName))
944                                {
945                                        retVal = entry;
946                                        break;
947                                }
948                        }
949                }
950                return retVal;
951        }
952 
953        /**
954         * (non-JSDoc)
955         * 
956         * @see org.deduced.viewer.web.shared.DynamicUserInterfaceService#updateReferenceList(java.lang.String,
957         *      java.util.ArrayList)
958         */
959        @Override
960        public void updateReferenceList(
961                final String objectID, final ArrayList<String> selectedObjectIDList)
962                throws Exception
963        {
964                if (LOGGER.isLoggable(Level.FINE))
965                {
966                        LOGGER.log(Level.FINE,
967                                "updateReferenceList entry : collection ID : \"" + objectID
968                                        + "\" reference list : \""
969                                        + printStringList(selectedObjectIDList) + "\".");
970                }
971 
972                try
973                {
974                        requestRunner.run(new ExceptionRunnable()
975                        {
976                                @Override
977                                public void runAndThrow() throws Exception
978                                {
979                                        runUpdateReferenceList(objectID, selectedObjectIDList);
980                                }
981                        });
982                }
983                catch (Exception e)
984                {
985                        if (LOGGER.isLoggable(Level.FINE))
986                        {
987                                LOGGER.log(
988                                        Level.FINE,
989                                        "updateReferenceList exit failed : collection ID : \""
990                                                + objectID + "\" reference list : \""
991                                                + printStringList(selectedObjectIDList) + "\". "
992                                                + e.getMessage(), e);
993                        }
994 
995                        throw convertToSerializableException(e);
996                }
997 
998                if (LOGGER.isLoggable(Level.FINE))
999                {
1000                        LOGGER.log(Level.FINE,
1001                                "updateReferenceList exit success : collection ID : \""
1002                                        + objectID + "\" reference list : \""
1003                                        + printStringList(selectedObjectIDList) + "\".");
1004                }
1005        }
1006 
1007        /**
1008         * convert an exception to one that can be serialized in the GWT layer
1009         * 
1010         * @param e the exception to convert
1011         * @return the converted exception.
1012         */
1013        public Exception convertToSerializableException(
1014                Exception e)
1015        {
1016                return new Exception(e.getMessage());
1017        }
1018 
1019        /**
1020         * 
1021         * print String List
1022         * 
1023         * @param stringList list to print
1024         * @return the printed string list
1025         */
1026        public static String printStringList(
1027                List<String> stringList)
1028        {
1029                if (stringList == null)
1030                {
1031                        return "null";
1032                }
1033 
1034                StringBuilder build = new StringBuilder();
1035 
1036                build.append("[ ");
1037 
1038                for (String string : stringList)
1039                {
1040                        build.append(string);
1041                        build.append(" ");
1042                }
1043 
1044                build.append("]");
1045 
1046                return build.toString();
1047        }
1048 
1049        /**
1050         * run Update Reference List
1051         * 
1052         * @param objectID the object ID to update
1053         * @param referencedObjectIDList the new reference list
1054         * @throws Exception any error encountered during the update
1055         */
1056        protected void runUpdateReferenceList(
1057                String objectID, List<String> referencedObjectIDList) throws Exception
1058        {
1059                try
1060                {
1061                        PropertyCollection collection = getCollectionFromStingID(objectID);
1062 
1063                        if (collection == null)
1064                        {
1065                                throw new IllegalArgumentException(
1066                                        "Unable to find collection of ID : \"" + objectID
1067                                                + "\" for which to update the reference list.");
1068                        }
1069                        List<PropertyCollection<?, ?>> selectionList =
1070                                new ArrayList<PropertyCollection<?, ?>>();
1071 
1072                        if (referencedObjectIDList != null)
1073                        {
1074                                for (String selectedID : referencedObjectIDList)
1075                                {
1076                                        PropertyCollection selectedCollection =
1077                                                getCollectionFromStingID(selectedID);
1078 
1079                                        if (selectedCollection == null)
1080                                        {
1081                                                throw new IllegalArgumentException(
1082                                                        "Unable to find collection of ID : \""
1083                                                                + selectedID
1084                                                                + "\" that should be placed in the selection list of collection ID \""
1085                                                                + objectID + "\"");
1086                                        }
1087                                        selectionList.add(selectedCollection);
1088                                }
1089                        }
1090 
1091                        DeductionRuleLibrary.fillList(collection, selectionList, true);
1092                }
1093                catch (Exception e)
1094                {
1095                        AssertUtilities.exception(e);
1096                        throw e;
1097                }
1098        }
1099 
1100        /**
1101         * get Collection From Sting ID
1102         * 
1103         * @param objectID the string object ID
1104         * @return the matching collection
1105         */
1106        public PropertyCollection<?, ?> getCollectionFromStingID(
1107                String objectID)
1108        {
1109                PropertyCollection<?, ?> retVal = null;
1110                try
1111                {
1112                        Long longObjectID = convertStringToObjectID(objectID);
1113                        retVal = listener.getCollection(longObjectID);
1114                }
1115                catch (Exception e)
1116                {
1117                        AssertUtilities.exception(e);
1118                }
1119                return retVal;
1120        }
1121 
1122        /**
1123         * convert String To ObjectID
1124         * 
1125         * @param objectID the object ID string
1126         * @return the integer object ID
1127         */
1128        public static Long convertStringToObjectID(
1129                String objectID)
1130        {
1131                return Long.valueOf(objectID);
1132        }
1133 
1134        /**
1135         * (non-JSDoc)
1136         * 
1137         * @see org.deduced.viewer.web.shared.DynamicUserInterfaceService#signalTriggered(java.lang.String,
1138         *      java.lang.String)
1139         */
1140        @Override
1141        public void signalTriggered(
1142                String objectID, final String signalName) throws Exception
1143        {
1144                if (LOGGER.isLoggable(Level.FINE))
1145                {
1146                        LOGGER.log(Level.FINE, "signalTriggered entry : collection ID : \""
1147                                + objectID + "\" signal named : \"" + signalName + "\".");
1148                }
1149 
1150                final PropertyCollection collection =
1151                        getCollectionFromStingID(objectID);
1152 
1153                if (collection == null)
1154                {
1155                        IllegalArgumentException iae =
1156                                new IllegalArgumentException(
1157                                        "signalTriggered : Unable to find collection ID : \""
1158                                                + objectID
1159                                                + "\" for which to trigger the signal named : \""
1160                                                + signalName + "\".");
1161 
1162                        if (LOGGER.isLoggable(Level.FINE))
1163                        {
1164                                LOGGER.log(Level.FINE,
1165                                        "signalTriggered exit failed : " + iae.getMessage(), iae);
1166                        }
1167 
1168                        throw convertToSerializableException(iae);
1169                }
1170 
1171                try
1172                {
1173                        requestRunner.run(new ExceptionRunnable()
1174                        {
1175                                @Override
1176                                public void runAndThrow() throws Exception
1177                                {
1178                                        collection.invokeAction(signalName, null);
1179                                }
1180                        });
1181                }
1182                catch (Exception e)
1183                {
1184                        IllegalArgumentException iae =
1185                                new IllegalArgumentException(
1186                                        "signalTriggered failed. Collection ID : \"" + objectID
1187                                                + "\" named \""
1188                                                + DeducedUtilities.getCollectionName(collection)
1189                                                + "\" of type \""
1190                                                + DeducedUtilities.getCollectionName(collection.type())
1191                                                + "\". Signal named : \"" + signalName + "\". Error : "
1192                                                + e.getMessage());
1193 
1194                        if (LOGGER.isLoggable(Level.FINE))
1195                        {
1196                                LOGGER.log(Level.FINE,
1197                                        "signalTriggered exit failed : " + iae.getMessage(), iae);
1198                        }
1199 
1200                        throw convertToSerializableException(iae);
1201                }
1202 
1203                if (LOGGER.isLoggable(Level.FINE))
1204                {
1205                        LOGGER.log(Level.FINE,
1206                                "signalTriggered exit success : collection ID : \"" + objectID
1207                                        + "\" signal named : \"" + signalName + "\".");
1208                }
1209        }
1210}

[all classes][org.deduced.viewer.web.server]
EMMA 2.0.9525 (unsupported private build) (C) Vladimir Roubtsov