Source Code Cross Referenced for NLSRefactoring.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » nls » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.corext.refactoring.nls 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.nls;
011:
012:        import java.util.ArrayList;
013:        import java.util.List;
014:
015:        import org.eclipse.core.runtime.Assert;
016:        import org.eclipse.core.runtime.CoreException;
017:        import org.eclipse.core.runtime.IPath;
018:        import org.eclipse.core.runtime.IProgressMonitor;
019:        import org.eclipse.core.runtime.OperationCanceledException;
020:        import org.eclipse.core.runtime.SubProgressMonitor;
021:
022:        import org.eclipse.core.resources.IFile;
023:        import org.eclipse.core.resources.IResource;
024:        import org.eclipse.core.resources.ResourcesPlugin;
025:
026:        import org.eclipse.ltk.core.refactoring.Change;
027:        import org.eclipse.ltk.core.refactoring.Refactoring;
028:        import org.eclipse.ltk.core.refactoring.RefactoringStatus;
029:        import org.eclipse.ltk.core.refactoring.RefactoringStatusContext;
030:        import org.eclipse.osgi.util.NLS;
031:
032:        import org.eclipse.jdt.core.ICompilationUnit;
033:        import org.eclipse.jdt.core.IPackageFragment;
034:        import org.eclipse.jdt.core.IType;
035:        import org.eclipse.jdt.core.JavaModelException;
036:        import org.eclipse.jdt.core.dom.CompilationUnit;
037:
038:        import org.eclipse.jdt.internal.corext.SourceRange;
039:        import org.eclipse.jdt.internal.corext.refactoring.Checks;
040:        import org.eclipse.jdt.internal.corext.refactoring.base.JavaStringStatusContext;
041:        import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange;
042:        import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
043:        import org.eclipse.jdt.internal.corext.util.Messages;
044:
045:        import org.eclipse.jdt.ui.SharedASTProvider;
046:
047:        public class NLSRefactoring extends Refactoring {
048:
049:            public static final String BUNDLE_NAME = "BUNDLE_NAME"; //$NON-NLS-1$
050:            public static final String PROPERTY_FILE_EXT = ".properties"; //$NON-NLS-1$
051:            public static final String DEFAULT_ACCESSOR_CLASSNAME = "Messages"; //$NON-NLS-1$
052:
053:            public static final String KEY = "${key}"; //$NON-NLS-1$
054:            public static final String DEFAULT_SUBST_PATTERN = "getString(" + KEY + ")"; //$NON-NLS-1$ //$NON-NLS-2$
055:
056:            public static final String DEFAULT_PROPERTY_FILENAME = "messages"; //$NON-NLS-1$
057:
058:            //private IPath fPropertyFilePath;
059:
060:            private String fAccessorClassName;
061:            private IPackageFragment fAccessorClassPackage;
062:            private String fResourceBundleName;
063:            private IPackageFragment fResourceBundlePackage;
064:
065:            private String fSubstitutionPattern;
066:            private ICompilationUnit fCu;
067:            private NLSSubstitution[] fSubstitutions;
068:
069:            private String fPrefix;
070:
071:            /**
072:             * <code>true</code> if the standard resource bundle mechanism
073:             * is used and <code>false</code> NLSing is done the Eclipse way. 
074:             */
075:            private boolean fIsEclipseNLS;
076:
077:            private NLSRefactoring(ICompilationUnit cu) {
078:                Assert.isNotNull(cu);
079:                fCu = cu;
080:
081:                CompilationUnit astRoot = SharedASTProvider.getAST(fCu,
082:                        SharedASTProvider.WAIT_YES, null);
083:                NLSHint nlsHint = new NLSHint(fCu, astRoot);
084:
085:                fSubstitutions = nlsHint.getSubstitutions();
086:                setAccessorClassName(nlsHint.getAccessorClassName());
087:                setAccessorClassPackage(nlsHint.getAccessorClassPackage());
088:                setIsEclipseNLS(detectIsEclipseNLS());
089:                setResourceBundleName(nlsHint.getResourceBundleName());
090:                setResourceBundlePackage(nlsHint.getResourceBundlePackage());
091:                setSubstitutionPattern(DEFAULT_SUBST_PATTERN);
092:
093:                String cuName = fCu.getElementName();
094:                if (fIsEclipseNLS)
095:                    setPrefix(cuName.substring(0, cuName.length() - 5) + "_"); // A.java -> A_ //$NON-NLS-1$
096:                else
097:                    setPrefix(cuName.substring(0, cuName.length() - 4)); // A.java -> A.
098:            }
099:
100:            public static NLSRefactoring create(ICompilationUnit cu) {
101:                if (cu == null || !cu.exists())
102:                    return null;
103:                return new NLSRefactoring(cu);
104:            }
105:
106:            /**
107:             * no validation is done
108:             * 
109:             * @param pattern
110:             *            Example: "Messages.getString(${key})". Must not be
111:             *            <code>null</code>. should (but does not have to) contain
112:             *            NLSRefactoring.KEY (default value is $key$) only the first
113:             *            occurrence of this key will be used
114:             */
115:            public void setSubstitutionPattern(String pattern) {
116:                Assert.isNotNull(pattern);
117:                fSubstitutionPattern = pattern;
118:            }
119:
120:            /**
121:             * to show the pattern in the UI
122:             * @return the substitution pattern
123:             */
124:            public String getSubstitutionPattern() {
125:                if (fIsEclipseNLS)
126:                    return KEY;
127:                else
128:                    return fSubstitutionPattern;
129:            }
130:
131:            public ICompilationUnit getCu() {
132:                return fCu;
133:            }
134:
135:            public String getName() {
136:                return Messages.format(
137:                        NLSMessages.NLSRefactoring_compilation_unit, fCu
138:                                .getElementName());
139:            }
140:
141:            public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
142:                    throws CoreException {
143:
144:                if (fSubstitutions.length == 0) {
145:                    String message = Messages.format(
146:                            NLSMessages.NLSRefactoring_no_strings, fCu
147:                                    .getElementName());
148:                    return RefactoringStatus.createFatalErrorStatus(message);
149:                }
150:                return new RefactoringStatus();
151:            }
152:
153:            public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
154:                    throws CoreException {
155:                checkParameters();
156:                try {
157:
158:                    pm.beginTask(NLSMessages.NLSRefactoring_checking, 5);
159:
160:                    RefactoringStatus result = new RefactoringStatus();
161:
162:                    result.merge(checkIfAnythingToDo());
163:                    if (result.hasFatalError()) {
164:                        return result;
165:                    }
166:                    pm.worked(1);
167:
168:                    result.merge(validateModifiesFiles());
169:                    if (result.hasFatalError()) {
170:                        return result;
171:                    }
172:                    pm.worked(1);
173:                    if (pm.isCanceled())
174:                        throw new OperationCanceledException();
175:
176:                    result.merge(checkSubstitutionPattern());
177:                    pm.worked(1);
178:
179:                    if (pm.isCanceled())
180:                        throw new OperationCanceledException();
181:
182:                    result.merge(checkKeys());
183:                    pm.worked(1);
184:                    if (pm.isCanceled())
185:                        throw new OperationCanceledException();
186:
187:                    if (!propertyFileExists() && willModifyPropertyFile()) {
188:                        String msg = Messages.format(
189:                                NLSMessages.NLSRefactoring_will_be_created,
190:                                getPropertyFilePath().toString());
191:                        result.addInfo(msg);
192:                    }
193:                    pm.worked(1);
194:
195:                    return result;
196:                } finally {
197:                    pm.done();
198:                }
199:            }
200:
201:            public Change createChange(IProgressMonitor pm)
202:                    throws CoreException {
203:                try {
204:                    checkParameters();
205:
206:                    pm.beginTask("", 3); //$NON-NLS-1$
207:
208:                    final DynamicValidationStateChange result = new DynamicValidationStateChange(
209:                            NLSMessages.NLSRefactoring_change_name);
210:
211:                    boolean createAccessorClass = willCreateAccessorClass();
212:                    if (NLSSubstitution.countItems(fSubstitutions,
213:                            NLSSubstitution.EXTERNALIZED) == 0) {
214:                        createAccessorClass = false;
215:                    }
216:                    if (createAccessorClass) {
217:                        result.add(AccessorClassCreator.create(fCu,
218:                                fAccessorClassName, getAccessorCUPath(),
219:                                fAccessorClassPackage, getPropertyFilePath(),
220:                                fIsEclipseNLS, fSubstitutions,
221:                                getSubstitutionPattern(),
222:                                new SubProgressMonitor(pm, 1)));
223:                    }
224:                    pm.worked(1);
225:
226:                    if (willModifySource()) {
227:                        result.add(NLSSourceModifier.create(getCu(),
228:                                fSubstitutions, getSubstitutionPattern(),
229:                                fAccessorClassPackage, fAccessorClassName,
230:                                fIsEclipseNLS));
231:                    }
232:                    pm.worked(1);
233:
234:                    if (willModifyPropertyFile()) {
235:                        result.add(NLSPropertyFileModifier.create(
236:                                fSubstitutions, getPropertyFilePath()));
237:                        if (isEclipseNLS() && !createAccessorClass) {
238:                            Change change = AccessorClassModifier.create(
239:                                    getAccessorCu(), fSubstitutions);
240:                            if (change != null)
241:                                result.add(change);
242:                        }
243:                    }
244:                    pm.worked(1);
245:
246:                    return result;
247:                } finally {
248:                    pm.done();
249:                }
250:            }
251:
252:            private void checkParameters() {
253:                Assert.isNotNull(fSubstitutions);
254:                Assert.isNotNull(fAccessorClassPackage);
255:
256:                // these values have defaults ...
257:                Assert.isNotNull(fAccessorClassName);
258:                Assert.isNotNull(getSubstitutionPattern());
259:            }
260:
261:            private IFile[] getAllFilesToModify() {
262:
263:                List files = new ArrayList(2);
264:                if (willModifySource()) {
265:                    IResource resource = fCu.getResource();
266:                    if (resource.exists()) {
267:                        files.add(resource);
268:                    }
269:                }
270:
271:                if (willModifyPropertyFile()) {
272:                    IFile file = getPropertyFileHandle();
273:                    if (file.exists()) {
274:                        files.add(file);
275:                    }
276:                }
277:
278:                if (willModifyAccessorClass()) {
279:                    IFile file = getAccessorClassFileHandle();
280:                    if (file.exists()) {
281:                        files.add(file);
282:                    }
283:                }
284:
285:                return (IFile[]) files.toArray(new IFile[files.size()]);
286:            }
287:
288:            public IFile getPropertyFileHandle() {
289:                return ResourcesPlugin.getWorkspace().getRoot().getFile(
290:                        getPropertyFilePath());
291:            }
292:
293:            public IPath getPropertyFilePath() {
294:                return fResourceBundlePackage.getPath().append(
295:                        fResourceBundleName);
296:            }
297:
298:            public IFile getAccessorClassFileHandle() {
299:                return ResourcesPlugin.getWorkspace().getRoot().getFile(
300:                        getAccessorClassFilePath());
301:            }
302:
303:            public IPath getAccessorClassFilePath() {
304:                return getAccessorCUPath();
305:            }
306:
307:            private RefactoringStatus validateModifiesFiles() {
308:                return Checks.validateModifiesFiles(getAllFilesToModify(),
309:                        getValidationContext());
310:            }
311:
312:            //should stop checking if fatal error
313:            private RefactoringStatus checkIfAnythingToDo()
314:                    throws JavaModelException {
315:                if (NLSSubstitution.countItems(fSubstitutions,
316:                        NLSSubstitution.EXTERNALIZED) != 0
317:                        && willCreateAccessorClass())
318:                    return null;
319:
320:                if (willModifyPropertyFile())
321:                    return null;
322:
323:                if (willModifySource())
324:                    return null;
325:
326:                RefactoringStatus result = new RefactoringStatus();
327:                result.addFatalError(NLSMessages.NLSRefactoring_nothing_to_do);
328:                return result;
329:            }
330:
331:            private boolean propertyFileExists() {
332:                return getPropertyFileHandle().exists();
333:            }
334:
335:            private RefactoringStatus checkSubstitutionPattern() {
336:                String pattern = getSubstitutionPattern();
337:
338:                RefactoringStatus result = new RefactoringStatus();
339:                if (pattern.trim().length() == 0) {// 
340:                    result.addError(NLSMessages.NLSRefactoring_pattern_empty);
341:                }
342:
343:                if (pattern.indexOf(KEY) == -1) {
344:                    String msg = Messages
345:                            .format(
346:                                    NLSMessages.NLSRefactoring_pattern_does_not_contain,
347:                                    KEY);
348:                    result.addWarning(msg);
349:                }
350:
351:                if (pattern.indexOf(KEY) != pattern.lastIndexOf(KEY)) {
352:                    String msg = Messages
353:                            .format(
354:                                    NLSMessages.NLSRefactoring_Only_the_first_occurrence_of,
355:                                    KEY);
356:                    result.addWarning(msg);
357:                }
358:
359:                return result;
360:            }
361:
362:            private RefactoringStatus checkKeys() {
363:                RefactoringStatus result = new RefactoringStatus();
364:                NLSSubstitution[] subs = fSubstitutions;
365:                for (int i = 0; i < subs.length; i++) {
366:                    NLSSubstitution substitution = subs[i];
367:                    if ((substitution.getState() == NLSSubstitution.EXTERNALIZED)
368:                            && substitution.hasStateChanged()) {
369:                        result.merge(checkKey(substitution.getKey()));
370:                    }
371:                }
372:                return result;
373:            }
374:
375:            private static RefactoringStatus checkKey(String key) {
376:                RefactoringStatus result = new RefactoringStatus();
377:
378:                if (key == null)
379:                    result.addFatalError(NLSMessages.NLSRefactoring_null);
380:
381:                if (key.startsWith("!") || key.startsWith("#")) { //$NON-NLS-1$ //$NON-NLS-2$
382:                    RefactoringStatusContext context = new JavaStringStatusContext(
383:                            key, new SourceRange(0, 0));
384:                    result.addWarning(NLSMessages.NLSRefactoring_warning,
385:                            context);
386:                }
387:
388:                if ("".equals(key.trim())) //$NON-NLS-1$
389:                    result.addFatalError(NLSMessages.NLSRefactoring_empty);
390:
391:                final String[] UNWANTED_STRINGS = {
392:                        " ", ":", "\"", "\\", "'", "?", "=" }; //$NON-NLS-7$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
393:                //feature in resource bundle - does not work properly if keys have ":"
394:                for (int i = 0; i < UNWANTED_STRINGS.length; i++) {
395:                    if (key.indexOf(UNWANTED_STRINGS[i]) != -1) {
396:                        String[] args = { key, UNWANTED_STRINGS[i] };
397:                        String msg = Messages.format(
398:                                NLSMessages.NLSRefactoring_should_not_contain,
399:                                args);
400:                        result.addError(msg);
401:                    }
402:                }
403:                return result;
404:            }
405:
406:            public boolean willCreateAccessorClass() throws JavaModelException {
407:
408:                ICompilationUnit compilationUnit = getAccessorCu();
409:                if (compilationUnit.exists()) {
410:                    return false;
411:                }
412:
413:                if (typeNameExistsInPackage(fAccessorClassPackage,
414:                        fAccessorClassName)) {
415:                    return false;
416:                }
417:
418:                return (!Checks.resourceExists(getAccessorCUPath()));
419:            }
420:
421:            private ICompilationUnit getAccessorCu() {
422:                return fAccessorClassPackage
423:                        .getCompilationUnit(getAccessorCUName());
424:            }
425:
426:            private boolean willModifySource() {
427:                NLSSubstitution[] subs = fSubstitutions;
428:                for (int i = 0; i < subs.length; i++) {
429:                    if (subs[i].hasSourceChange())
430:                        return true;
431:                }
432:                return false;
433:            }
434:
435:            private boolean willModifyPropertyFile() {
436:                NLSSubstitution[] subs = fSubstitutions;
437:                for (int i = 0; i < subs.length; i++) {
438:                    NLSSubstitution substitution = subs[i];
439:                    if (substitution.hasPropertyFileChange()) {
440:                        return true;
441:                    }
442:                }
443:                return false;
444:            }
445:
446:            private boolean willModifyAccessorClass() {
447:                if (!isEclipseNLS())
448:                    return false;
449:
450:                NLSSubstitution[] subs = fSubstitutions;
451:                for (int i = 0; i < subs.length; i++) {
452:                    NLSSubstitution substitution = subs[i];
453:                    if (substitution.hasAccessorClassChange()) {
454:                        return true;
455:                    }
456:                }
457:                return false;
458:            }
459:
460:            private boolean typeNameExistsInPackage(IPackageFragment pack,
461:                    String name) throws JavaModelException {
462:                return Checks.findTypeInPackage(pack, name) != null;
463:            }
464:
465:            private String getAccessorCUName() {
466:                return getAccessorClassName() + JavaModelUtil.DEFAULT_CU_SUFFIX;
467:            }
468:
469:            private IPath getAccessorCUPath() {
470:                return fAccessorClassPackage.getPath().append(
471:                        getAccessorCUName());
472:            }
473:
474:            public NLSSubstitution[] getSubstitutions() {
475:                return fSubstitutions;
476:            }
477:
478:            public String getPrefix() {
479:                return fPrefix;
480:            }
481:
482:            public void setPrefix(String prefix) {
483:                fPrefix = prefix;
484:                if (fSubstitutions != null) {
485:                    for (int i = 0; i < fSubstitutions.length; i++)
486:                        fSubstitutions[i].setPrefix(prefix);
487:                }
488:            }
489:
490:            public void setAccessorClassName(String name) {
491:                Assert.isNotNull(name);
492:                fAccessorClassName = name;
493:            }
494:
495:            public void setAccessorClassPackage(IPackageFragment packageFragment) {
496:                Assert.isNotNull(packageFragment);
497:                fAccessorClassPackage = packageFragment;
498:            }
499:
500:            /**
501:             * Sets whether the Eclipse NLSing mechanism or
502:             * standard resource bundle mechanism is used.
503:             * 
504:             * @param isEclipseNLS	<code>true</code> if NLSing is done the Eclipse way
505:             * 						and <code>false</code> if the standard resource bundle mechanism is used
506:             * @since 3.1 
507:             */
508:            public void setIsEclipseNLS(boolean isEclipseNLS) {
509:                fIsEclipseNLS = isEclipseNLS;
510:            }
511:
512:            public void setResourceBundlePackage(
513:                    IPackageFragment resourceBundlePackage) {
514:                Assert.isNotNull(resourceBundlePackage);
515:                fResourceBundlePackage = resourceBundlePackage;
516:            }
517:
518:            public void setResourceBundleName(String resourceBundleName) {
519:                Assert.isNotNull(resourceBundleName);
520:                fResourceBundleName = resourceBundleName;
521:            }
522:
523:            public IPackageFragment getAccessorClassPackage() {
524:                return fAccessorClassPackage;
525:            }
526:
527:            /**
528:             * Computes whether the Eclipse NLSing mechanism is used.
529:             * 
530:             * @return		<code>true</code> if NLSing is done the Eclipse way
531:             * 				and <code>false</code> if the standard resource bundle mechanism is used
532:             * @since 3.1 
533:             */
534:            public boolean detectIsEclipseNLS() {
535:                if (getAccessorClassPackage() != null) {
536:                    ICompilationUnit accessorCU = getAccessorClassPackage()
537:                            .getCompilationUnit(getAccessorCUName());
538:                    IType type = accessorCU.getType(getAccessorClassName());
539:                    if (type.exists()) {
540:                        try {
541:                            String super className = type.getSuperclassName();
542:                            if (!"NLS".equals(super className) && !NLS.class.getName().equals(super className)) //$NON-NLS-1$
543:                                return false;
544:                            IType super class = type.newSupertypeHierarchy(null)
545:                                    .getSuperclass(type);
546:                            return super class != null
547:                                    && NLS.class.getName().equals(
548:                                            super class.getFullyQualifiedName());
549:                        } catch (JavaModelException e) {
550:                            return false;
551:                        }
552:                    }
553:                }
554:                return fIsEclipseNLS;
555:            }
556:
557:            /**
558:             * Returns whether the Eclipse NLSing mechanism or
559:             * the standard resource bundle mechanism is used.
560:             * 
561:             * @return		<code>true</code> if NLSing is done the Eclipse way
562:             * 				and <code>false</code> if the standard resource bundle mechanism is used
563:             * @since 3.1 
564:             */
565:            public boolean isEclipseNLS() {
566:                return fIsEclipseNLS;
567:            }
568:
569:            public IPackageFragment getResourceBundlePackage() {
570:                return fResourceBundlePackage;
571:            }
572:
573:            public String getAccessorClassName() {
574:                return fAccessorClassName;
575:            }
576:
577:            public String getResourceBundleName() {
578:                return fResourceBundleName;
579:            }
580:        }
w___w_w.___j___a__v___a___2_s._c___o___m__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.