1
22
23 package com.liferay.portal.deploy.hot;
24
25 import com.liferay.portal.apache.bridges.struts.LiferayServletContextProvider;
26 import com.liferay.portal.kernel.cache.CacheRegistry;
27 import com.liferay.portal.kernel.configuration.Configuration;
28 import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
29 import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
30 import com.liferay.portal.kernel.deploy.hot.HotDeployException;
31 import com.liferay.portal.kernel.job.Scheduler;
32 import com.liferay.portal.kernel.language.LanguageUtil;
33 import com.liferay.portal.kernel.lar.PortletDataHandler;
34 import com.liferay.portal.kernel.pop.MessageListener;
35 import com.liferay.portal.kernel.portlet.ConfigurationAction;
36 import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
37 import com.liferay.portal.kernel.portlet.PortletLayoutListener;
38 import com.liferay.portal.kernel.search.Indexer;
39 import com.liferay.portal.kernel.servlet.PortletServlet;
40 import com.liferay.portal.kernel.servlet.ServletContextProvider;
41 import com.liferay.portal.kernel.servlet.URLEncoder;
42 import com.liferay.portal.kernel.util.ClassUtil;
43 import com.liferay.portal.kernel.util.GetterUtil;
44 import com.liferay.portal.kernel.util.HttpUtil;
45 import com.liferay.portal.kernel.util.LocaleUtil;
46 import com.liferay.portal.kernel.util.ObjectValuePair;
47 import com.liferay.portal.kernel.util.StringUtil;
48 import com.liferay.portal.kernel.util.Validator;
49 import com.liferay.portal.model.Portlet;
50 import com.liferay.portal.model.PortletApp;
51 import com.liferay.portal.model.PortletCategory;
52 import com.liferay.portal.model.PortletFilter;
53 import com.liferay.portal.model.PortletURLListener;
54 import com.liferay.portal.pop.POPServerUtil;
55 import com.liferay.portal.security.permission.ResourceActionsUtil;
56 import com.liferay.portal.service.PortletLocalServiceUtil;
57 import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
58 import com.liferay.portal.util.Portal;
59 import com.liferay.portal.util.PortalInstances;
60 import com.liferay.portal.util.PropsValues;
61 import com.liferay.portal.util.WebAppPool;
62 import com.liferay.portal.util.WebKeys;
63 import com.liferay.portlet.CustomUserAttributes;
64 import com.liferay.portlet.PortletBag;
65 import com.liferay.portlet.PortletBagPool;
66 import com.liferay.portlet.PortletConfigFactory;
67 import com.liferay.portlet.PortletContextBag;
68 import com.liferay.portlet.PortletContextBagPool;
69 import com.liferay.portlet.PortletFilterFactory;
70 import com.liferay.portlet.PortletInstanceFactory;
71 import com.liferay.portlet.PortletPreferencesSerializer;
72 import com.liferay.portlet.PortletResourceBundles;
73 import com.liferay.portlet.PortletURLListenerFactory;
74 import com.liferay.portlet.social.model.SocialActivityInterpreter;
75 import com.liferay.portlet.social.model.SocialRequestInterpreter;
76 import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
77 import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
78 import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
79 import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
80
81 import java.util.HashMap;
82 import java.util.HashSet;
83 import java.util.Iterator;
84 import java.util.List;
85 import java.util.Locale;
86 import java.util.Map;
87 import java.util.MissingResourceException;
88 import java.util.Properties;
89 import java.util.ResourceBundle;
90 import java.util.Set;
91
92 import javax.portlet.PortletConfig;
93 import javax.portlet.PortletContext;
94 import javax.portlet.PortletURLGenerationListener;
95 import javax.portlet.PreferencesValidator;
96
97 import javax.servlet.ServletContext;
98
99 import org.apache.commons.logging.Log;
100 import org.apache.commons.logging.LogFactory;
101 import org.apache.portals.bridges.struts.StrutsPortlet;
102
103
111 public class PortletHotDeployListener extends BaseHotDeployListener {
112
113 public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
114 try {
115 doInvokeDeploy(event);
116 }
117 catch (Exception e) {
118 throwHotDeployException(
119 event, "Error registering portlets for ", e);
120 }
121 }
122
123 public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
124 try {
125 doInvokeUndeploy(event);
126 }
127 catch (Exception e) {
128 throwHotDeployException(
129 event, "Error unregistering portlets for ", e);
130 }
131 }
132
133 protected void destroyPortlet(Portlet portlet, Set<String> portletIds)
134 throws Exception {
135
136 PortletApp portletApp = portlet.getPortletApp();
137
138 Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
139
140 for (PortletFilter portletFilter : portletFilters) {
141 PortletFilterFactory.destroy(portletFilter);
142 }
143
144 Set<PortletURLListener> portletURLListeners =
145 portletApp.getPortletURLListeners();
146
147 for (PortletURLListener portletURLListener : portletURLListeners) {
148 PortletURLListenerFactory.destroy(portletURLListener);
149 }
150
151 Scheduler scheduler = portlet.getSchedulerInstance();
152
153 if (scheduler != null) {
154 scheduler.unschedule();
155 }
156
157 POPServerUtil.deleteListener(portlet.getPopMessageListenerInstance());
158
159 SocialActivityInterpreterLocalServiceUtil.deleteActivityInterpreter(
160 portlet.getSocialActivityInterpreterInstance());
161
162 SocialRequestInterpreterLocalServiceUtil.deleteRequestInterpreter(
163 portlet.getSocialRequestInterpreterInstance());
164
165 PortletInstanceFactory.destroy(portlet);
166
167 portletIds.add(portlet.getPortletId());
168 }
169
170 protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
171
172
174 ServletContext servletContext = event.getServletContext();
175
176 String servletContextName = servletContext.getServletContextName();
177
178 if (_log.isDebugEnabled()) {
179 _log.debug("Invoking deploy for " + servletContextName);
180 }
181
182
184 long[] companyIds = PortalInstances.getCompanyIds();
185
186
188 String[] xmls = new String[] {
189 HttpUtil.URLtoString(servletContext.getResource(
190 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD)),
191 HttpUtil.URLtoString(servletContext.getResource(
192 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
193 HttpUtil.URLtoString(servletContext.getResource(
194 "/WEB-INF/liferay-portlet.xml")),
195 HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
196 };
197
198 if (xmls[0] == null) {
199 return;
200 }
201
202 if (_log.isInfoEnabled()) {
203 _log.info("Registering portlets for " + servletContextName);
204 }
205
206 List<Portlet> portlets = PortletLocalServiceUtil.initWAR(
207 servletContextName, xmls, event.getPluginPackage());
208
209 if (_log.isInfoEnabled()) {
210 _log.info(
211 portlets.size() + " portlets for " + servletContextName +
212 " are ready for registration");
213 }
214
215
217 ClassLoader portletClassLoader = event.getContextClassLoader();
218
219 servletContext.setAttribute(
220 PortletServlet.PORTLET_CLASS_LOADER, portletClassLoader);
221
222
224 _strutsBridges = false;
225
226 Iterator<Portlet> portletsItr = portlets.iterator();
227
228 while (portletsItr.hasNext()) {
229 Portlet portlet = portletsItr.next();
230
231 initPortlet(
232 portlet, servletContext, portletClassLoader, portletsItr);
233 }
234
235
237 if (!_strutsBridges) {
238 _strutsBridges = GetterUtil.getBoolean(
239 servletContext.getInitParameter(
240 "struts-bridges-context-provider"));
241 }
242
243 if (_strutsBridges) {
244 servletContext.setAttribute(
245 ServletContextProvider.STRUTS_BRIDGES_CONTEXT_PROVIDER,
246 new LiferayServletContextProvider());
247 }
248
249
251 String xml = HttpUtil.URLtoString(servletContext.getResource(
252 "/WEB-INF/liferay-display.xml"));
253
254 PortletCategory newPortletCategory =
255 PortletLocalServiceUtil.getWARDisplay(servletContextName, xml);
256
257 for (int i = 0; i < companyIds.length; i++) {
258 long companyId = companyIds[i];
259
260 PortletCategory portletCategory =
261 (PortletCategory)WebAppPool.get(
262 String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
263
264 if (portletCategory != null) {
265 portletCategory.merge(newPortletCategory);
266 }
267 else {
268 _log.error(
269 "Unable to register portlet for company " + companyId +
270 " because it does not exist");
271 }
272 }
273
274
276 processPortletProperties(servletContextName, portletClassLoader);
277
278
280 _processServiceBuilderProperties = false;
281
282 processServiceBuilderProperties(servletContext, portletClassLoader);
283
284
286 _vars.put(
287 servletContextName,
288 new ObjectValuePair<long[], List<Portlet>>(
289 companyIds, portlets));
290
291 if (_log.isInfoEnabled()) {
292 _log.info(
293 portlets.size() + " portlets for " + servletContextName +
294 " registered successfully");
295 }
296 }
297
298 protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
299 ServletContext servletContext = event.getServletContext();
300
301 String servletContextName = servletContext.getServletContextName();
302
303 if (_log.isDebugEnabled()) {
304 _log.debug("Invoking undeploy for " + servletContextName);
305 }
306
307 ObjectValuePair<long[], List<Portlet>> ovp =
308 _vars.remove(servletContextName);
309
310 if (ovp == null) {
311 return;
312 }
313
314 long[] companyIds = ovp.getKey();
315 List<Portlet> portlets = ovp.getValue();
316
317 Set<String> portletIds = new HashSet<String>();
318
319 if (portlets != null) {
320 if (_log.isInfoEnabled()) {
321 _log.info(
322 "Unregistering portlets for " + servletContextName);
323 }
324
325 Iterator<Portlet> itr = portlets.iterator();
326
327 while (itr.hasNext()) {
328 Portlet portlet = itr.next();
329
330 destroyPortlet(portlet, portletIds);
331 }
332 }
333
334 if (portletIds.size() > 0) {
335 for (int i = 0; i < companyIds.length; i++) {
336 long companyId = companyIds[i];
337
338 PortletCategory portletCategory =
339 (PortletCategory)WebAppPool.get(
340 String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
341
342 portletCategory.separate(portletIds);
343 }
344 }
345
346 PortletResourceBundles.remove(servletContextName);
347
348 if (_processServiceBuilderProperties) {
349 CacheRegistry.clear();
350 }
351
352 if (_log.isInfoEnabled()) {
353 _log.info(
354 portlets.size() + " portlets for " + servletContextName +
355 " unregistered successfully");
356 }
357 }
358
359 protected void initPortlet(
360 Portlet portlet, ServletContext servletContext,
361 ClassLoader portletClassLoader, Iterator<Portlet> portletsItr)
362 throws Exception {
363
364 Class<?> portletClass = null;
365
366 try {
367 portletClass = portletClassLoader.loadClass(
368 portlet.getPortletClass());
369 }
370 catch (Exception e) {
371 _log.error(e, e);
372
373 portletsItr.remove();
374
375 PortletLocalServiceUtil.destroyPortlet(portlet);
376
377 return;
378 }
379
380 javax.portlet.Portlet portletInstance =
381 (javax.portlet.Portlet)portletClass.newInstance();
382
383 if (ClassUtil.isSubclass(portletClass, StrutsPortlet.class.getName())) {
384 _strutsBridges = true;
385 }
386
387 ConfigurationAction configurationActionInstance = null;
388
389 if (Validator.isNotNull(portlet.getConfigurationActionClass())) {
390 configurationActionInstance =
391 (ConfigurationAction)portletClassLoader.loadClass(
392 portlet.getConfigurationActionClass()).newInstance();
393 }
394
395 Indexer indexerInstance = null;
396
397 if (Validator.isNotNull(portlet.getIndexerClass())) {
398 indexerInstance = (Indexer)portletClassLoader.loadClass(
399 portlet.getIndexerClass()).newInstance();
400 }
401
402 Scheduler schedulerInstance = null;
403
404 if (PropsValues.SCHEDULER_ENABLED &&
405 Validator.isNotNull(portlet.getSchedulerClass())) {
406
407 schedulerInstance = (Scheduler)portletClassLoader.loadClass(
408 portlet.getSchedulerClass()).newInstance();
409
410 schedulerInstance.schedule();
411 }
412
413 FriendlyURLMapper friendlyURLMapperInstance = null;
414
415 if (Validator.isNotNull(portlet.getFriendlyURLMapperClass())) {
416 friendlyURLMapperInstance =
417 (FriendlyURLMapper)portletClassLoader.loadClass(
418 portlet.getFriendlyURLMapperClass()).newInstance();
419 }
420
421 URLEncoder urlEncoderInstance = null;
422
423 if (Validator.isNotNull(portlet.getURLEncoderClass())) {
424 urlEncoderInstance = (URLEncoder)portletClassLoader.loadClass(
425 portlet.getURLEncoderClass()).newInstance();
426 }
427
428 PortletDataHandler portletDataHandlerInstance = null;
429
430 if (Validator.isNotNull(portlet.getPortletDataHandlerClass())) {
431 portletDataHandlerInstance =
432 (PortletDataHandler)portletClassLoader.loadClass(
433 portlet.getPortletDataHandlerClass()).newInstance();
434 }
435
436 PortletLayoutListener portletLayoutListenerInstance = null;
437
438 if (Validator.isNotNull(portlet.getPortletLayoutListenerClass())) {
439 portletLayoutListenerInstance =
440 (PortletLayoutListener)portletClassLoader.loadClass(
441 portlet.getPortletLayoutListenerClass()).newInstance();
442 }
443
444 MessageListener popMessageListenerInstance = null;
445
446 if (Validator.isNotNull(portlet.getPopMessageListenerClass())) {
447 popMessageListenerInstance =
448 (MessageListener)portletClassLoader.loadClass(
449 portlet.getPopMessageListenerClass()).newInstance();
450
451 POPServerUtil.addListener(popMessageListenerInstance);
452 }
453
454 SocialActivityInterpreter socialActivityInterpreterInstance = null;
455
456 if (Validator.isNotNull(portlet.getSocialActivityInterpreterClass())) {
457 socialActivityInterpreterInstance =
458 (SocialActivityInterpreter)portletClassLoader.loadClass(
459 portlet.getSocialActivityInterpreterClass()).newInstance();
460
461 socialActivityInterpreterInstance =
462 new SocialActivityInterpreterImpl(
463 portlet.getPortletId(), socialActivityInterpreterInstance);
464
465 SocialActivityInterpreterLocalServiceUtil.addActivityInterpreter(
466 socialActivityInterpreterInstance);
467 }
468
469 SocialRequestInterpreter socialRequestInterpreterInstance = null;
470
471 if (Validator.isNotNull(portlet.getSocialRequestInterpreterClass())) {
472 socialRequestInterpreterInstance =
473 (SocialRequestInterpreter)portletClassLoader.loadClass(
474 portlet.getSocialRequestInterpreterClass()).newInstance();
475
476 socialRequestInterpreterInstance = new SocialRequestInterpreterImpl(
477 portlet.getPortletId(), socialRequestInterpreterInstance);
478
479 SocialRequestInterpreterLocalServiceUtil.addRequestInterpreter(
480 socialRequestInterpreterInstance);
481 }
482
483 PreferencesValidator prefsValidatorInstance = null;
484
485 if (Validator.isNotNull(portlet.getPreferencesValidator())) {
486 prefsValidatorInstance =
487 (PreferencesValidator)portletClassLoader.loadClass(
488 portlet.getPreferencesValidator()).newInstance();
489
490 try {
491 if (PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
492 prefsValidatorInstance.validate(
493 PortletPreferencesSerializer.fromDefaultXML(
494 portlet.getDefaultPreferences()));
495 }
496 }
497 catch (Exception e) {
498 _log.warn(
499 "Portlet with the name " + portlet.getPortletId() +
500 " does not have valid default preferences");
501 }
502 }
503
504 Map<String, ResourceBundle> resourceBundles = null;
505
506 if (Validator.isNotNull(portlet.getResourceBundle())) {
507 resourceBundles = new HashMap<String, ResourceBundle>();
508
509 initResourceBundle(
510 resourceBundles, portlet, portletClassLoader,
511 LocaleUtil.getDefault());
512
513 Iterator<String> supportLocalesItr =
514 portlet.getSupportedLocales().iterator();
515
516 while (supportLocalesItr.hasNext()) {
517 String supportedLocale = supportLocalesItr.next();
518
519 Locale locale = LocaleUtil.fromLanguageId(supportedLocale);
520
521 initResourceBundle(
522 resourceBundles, portlet, portletClassLoader, locale);
523 }
524 }
525
526 PortletBag portletBag = new PortletBag(
527 portlet.getPortletId(), servletContext, portletInstance,
528 configurationActionInstance, indexerInstance, schedulerInstance,
529 friendlyURLMapperInstance, urlEncoderInstance,
530 portletDataHandlerInstance, portletLayoutListenerInstance,
531 popMessageListenerInstance, socialActivityInterpreterInstance,
532 socialRequestInterpreterInstance, prefsValidatorInstance,
533 resourceBundles);
534
535 PortletBagPool.put(portlet.getPortletId(), portletBag);
536
537 if (!portletsItr.hasNext()) {
538 initPortletApp(portlet, servletContext, portletClassLoader);
539 }
540
541 try {
542 PortletInstanceFactory.create(portlet, servletContext);
543 }
544 catch (Exception e) {
545 _log.error(e, e);
546 }
547 }
548
549 protected void initPortletApp(
550 Portlet portlet, ServletContext servletContext,
551 ClassLoader portletClassLoader)
552 throws Exception {
553
554 String servletContextName = servletContext.getServletContextName();
555
556 PortletConfig portletConfig = PortletConfigFactory.create(
557 portlet, servletContext);
558
559 PortletContext portletContext = portletConfig.getPortletContext();
560
561 PortletContextBag portletContextBag = new PortletContextBag(
562 servletContextName);
563
564 PortletContextBagPool.put(servletContextName, portletContextBag);
565
566 PortletApp portletApp = portlet.getPortletApp();
567
568 Map<String, String> customUserAttributes =
569 portletApp.getCustomUserAttributes();
570
571 for (Map.Entry<String, String> entry :
572 customUserAttributes.entrySet()) {
573
574 String attrCustomClass = entry.getValue();
575
576 CustomUserAttributes customUserAttributesInstance =
577 (CustomUserAttributes)portletClassLoader.loadClass(
578 attrCustomClass).newInstance();
579
580 portletContextBag.getCustomUserAttributes().put(
581 attrCustomClass, customUserAttributesInstance);
582 }
583
584 Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
585
586 for (PortletFilter portletFilter : portletFilters) {
587 javax.portlet.filter.PortletFilter portletFilterInstance =
588 (javax.portlet.filter.PortletFilter)
589 portletClassLoader.loadClass(
590 portletFilter.getFilterClass()).newInstance();
591
592 portletContextBag.getPortletFilters().put(
593 portletFilter.getFilterName(), portletFilterInstance);
594
595 PortletFilterFactory.create(portletFilter, portletContext);
596 }
597
598 Set<PortletURLListener> portletURLListeners =
599 portletApp.getPortletURLListeners();
600
601 for (PortletURLListener portletURLListener : portletURLListeners) {
602 PortletURLGenerationListener portletURLListenerInstance =
603 (PortletURLGenerationListener)portletClassLoader.loadClass(
604 portletURLListener.getListenerClass()).newInstance();
605
606 portletContextBag.getPortletURLListeners().put(
607 portletURLListener.getListenerClass(),
608 portletURLListenerInstance);
609
610 PortletURLListenerFactory.create(portletURLListener);
611 }
612 }
613
614 protected void initResourceBundle(
615 Map<String, ResourceBundle> resourceBundles, Portlet portlet,
616 ClassLoader portletClassLoader, Locale locale) {
617
618 try {
619 ResourceBundle resourceBundle = ResourceBundle.getBundle(
620 portlet.getResourceBundle(), locale, portletClassLoader);
621
622 resourceBundles.put(
623 LocaleUtil.toLanguageId(locale), resourceBundle);
624 }
625 catch (MissingResourceException mre) {
626 _log.warn(mre.getMessage());
627 }
628 }
629
630 protected void processPortletProperties(
631 String servletContextName, ClassLoader portletClassLoader)
632 throws Exception {
633
634 Configuration portletPropertiesConfiguration = null;
635
636 try {
637 portletPropertiesConfiguration =
638 ConfigurationFactoryUtil.getConfiguration(
639 portletClassLoader, "portlet");
640 }
641 catch (Exception e) {
642 if (_log.isDebugEnabled()) {
643 _log.debug("Unable to read portlet.properties");
644 }
645 }
646
647 if (portletPropertiesConfiguration == null) {
648 return;
649 }
650
651 Properties portletProperties =
652 portletPropertiesConfiguration.getProperties();
653
654 if (portletProperties.size() == 0) {
655 return;
656 }
657
658 String languageBundleName = portletProperties.getProperty(
659 "language.bundle");
660
661 if (Validator.isNotNull(languageBundleName)) {
662 Locale[] locales = LanguageUtil.getAvailableLocales();
663
664 for (int i = 0; i < locales.length; i++) {
665 ResourceBundle bundle = ResourceBundle.getBundle(
666 languageBundleName, locales[i], portletClassLoader);
667
668 PortletResourceBundles.put(
669 servletContextName, LocaleUtil.toLanguageId(locales[i]),
670 bundle);
671 }
672 }
673
674 String[] resourceActionConfigs = StringUtil.split(
675 portletProperties.getProperty("resource.actions.configs"));
676
677 for (int i = 0; i < resourceActionConfigs.length; i++) {
678 ResourceActionsUtil.read(
679 servletContextName, portletClassLoader,
680 resourceActionConfigs[i]);
681 }
682 }
683
684 protected void processServiceBuilderProperties(
685 ServletContext servletContext, ClassLoader portletClassLoader)
686 throws Exception {
687
688 Configuration serviceBuilderPropertiesConfiguration = null;
689
690 try {
691 serviceBuilderPropertiesConfiguration =
692 ConfigurationFactoryUtil.getConfiguration(
693 portletClassLoader, "service");
694 }
695 catch (Exception e) {
696 if (_log.isDebugEnabled()) {
697 _log.debug("Unable to read service.properties");
698 }
699 }
700
701 if (serviceBuilderPropertiesConfiguration == null) {
702 return;
703 }
704
705 Properties serviceBuilderProperties =
706 serviceBuilderPropertiesConfiguration.getProperties();
707
708 if (serviceBuilderProperties.size() == 0) {
709 return;
710 }
711
712 String buildNamespace = GetterUtil.getString(
713 serviceBuilderProperties.getProperty("build.namespace"));
714 long buildNumber = GetterUtil.getLong(
715 serviceBuilderProperties.getProperty("build.number"));
716 long buildDate = GetterUtil.getLong(
717 serviceBuilderProperties.getProperty("build.date"));
718
719 if (_log.isDebugEnabled()) {
720 _log.debug("Build namespace " + buildNamespace);
721 _log.debug("Build number " + buildNumber);
722 _log.debug("Build date " + buildDate);
723 }
724
725 ServiceComponentLocalServiceUtil.updateServiceComponent(
726 servletContext, portletClassLoader, buildNamespace, buildNumber,
727 buildDate);
728
729 _processServiceBuilderProperties = true;
730 }
731
732 private static Log _log = LogFactory.getLog(PortletHotDeployListener.class);
733
734 private static Map<String, ObjectValuePair<long[], List<Portlet>>> _vars =
735 new HashMap<String, ObjectValuePair<long[], List<Portlet>>>();
736
737 private boolean _strutsBridges;
738 private boolean _processServiceBuilderProperties;
739
740 }