From f0797f0026f729fa612930fbd0acefc5343a0fe6 Mon Sep 17 00:00:00 2001 From: nash Date: Mon, 22 Nov 2010 09:49:22 +0000 Subject: Copy 1.6.1-RC2 tag as 1.6.1 git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1037648 13f79535-47bb-0310-9956-ffa450edef68 --- .../tags/1.6.1/modules/domain-manager/LICENSE | 205 ++++++ .../tags/1.6.1/modules/domain-manager/NOTICE | 6 + .../tags/1.6.1/modules/domain-manager/pom.xml | 227 +++++++ .../impl/CompositeConfigurationCollectionImpl.java | 127 ++++ .../impl/CompositeConfigurationServiceImpl.java | 657 +++++++++++++++++++ .../impl/CompositeGeneratorServiceImpl.java | 255 ++++++++ .../manager/impl/ContributionCollectionImpl.java | 705 +++++++++++++++++++++ .../manager/impl/ContributionServiceImpl.java | 77 +++ .../domain/manager/impl/ContributionsReader.java | 27 + .../impl/DeployableCompositeCollectionImpl.java | 481 ++++++++++++++ .../impl/DeployableCompositeServiceImpl.java | 128 ++++ .../impl/DeployedCompositeCollectionImpl.java | 417 ++++++++++++ .../manager/impl/DomainManagerConfiguration.java | 53 ++ .../impl/DomainManagerConfigurationImpl.java | 85 +++ .../sca/domain/manager/impl/DomainManagerUtil.java | 295 +++++++++ .../domain/manager/impl/FileCollectionImpl.java | 136 ++++ .../sca/domain/manager/impl/FileServiceImpl.java | 210 ++++++ .../manager/impl/NodeConfigurationServiceImpl.java | 96 +++ .../impl/NodeProcessCollectionFacadeImpl.java | 251 ++++++++ .../domain/manager/impl/QuickStartServiceImpl.java | 242 +++++++ .../tuscany/sca/domain/manager/impl/Searcher.java | 479 ++++++++++++++ .../launcher/DomainManagerLauncherBootstrap.java | 90 +++ .../src/main/resources/DomainManager.composite | 318 ++++++++++ .../src/main/resources/cloud-gadget.html | 409 ++++++++++++ .../domain-manager/src/main/resources/cloud.html | 68 ++ .../src/main/resources/composite-gadget.html | 278 ++++++++ .../src/main/resources/composite.html | 66 ++ .../src/main/resources/files-gadget.html | 124 ++++ .../domain-manager/src/main/resources/files.html | 64 ++ .../src/main/resources/home-gadget.html | 36 ++ .../domain-manager/src/main/resources/home.html | 62 ++ .../src/main/resources/icons/artifact.png | Bin 0 -> 228 bytes .../src/main/resources/icons/component.png | Bin 0 -> 226 bytes .../src/main/resources/icons/composite.png | Bin 0 -> 202 bytes .../src/main/resources/icons/feed-icon.png | Bin 0 -> 818 bytes .../domain-manager/src/main/resources/manager.css | 104 +++ .../src/main/resources/search-gadget.html | 100 +++ .../domain-manager/src/main/resources/search.html | 127 ++++ .../src/main/resources/toolbar-gadget.html | 59 ++ .../domain-manager/src/main/resources/utils.js | 248 ++++++++ .../src/main/resources/workspace-gadget.html | 232 +++++++ .../src/main/resources/workspace.html | 65 ++ .../domain/manager/impl/DomainManagerTestCase.java | 117 ++++ .../assets/META-INF/sca-contribution.xml | 26 + .../store/META-INF/sca-contribution.xml | 24 + .../src/test/resources/workspace.xml | 21 + 46 files changed, 7797 insertions(+) create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/LICENSE create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/NOTICE create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/pom.xml create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationCollectionImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeGeneratorServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionCollectionImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionsReader.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeCollectionImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployedCompositeCollectionImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfiguration.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfigurationImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerUtil.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileCollectionImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeConfigurationServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeProcessCollectionFacadeImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/QuickStartServiceImpl.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/Searcher.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/launcher/DomainManagerLauncherBootstrap.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/DomainManager.composite create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/artifact.png create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/component.png create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/composite.png create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/feed-icon.png create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/manager.css create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/toolbar-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/utils.js create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace-gadget.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace.html create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerTestCase.java create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/assets/META-INF/sca-contribution.xml create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/store/META-INF/sca-contribution.xml create mode 100644 sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/workspace.xml (limited to 'sca-java-1.x/tags/1.6.1/modules/domain-manager') diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/LICENSE b/sca-java-1.x/tags/1.6.1/modules/domain-manager/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/NOTICE b/sca-java-1.x/tags/1.6.1/modules/domain-manager/NOTICE new file mode 100644 index 0000000000..9ddba06a32 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/NOTICE @@ -0,0 +1,6 @@ +${pom.name} +Copyright (c) 2005 - 2010 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/pom.xml b/sca-java-1.x/tags/1.6.1/modules/domain-manager/pom.xml new file mode 100644 index 0000000000..7a8fea6ffe --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/pom.xml @@ -0,0 +1,227 @@ + + + + 4.0.0 + + org.apache.tuscany.sca + tuscany-modules + 1.6.1 + ../pom.xml + + tuscany-domain-manager + Apache Tuscany SCA Domain Manager Application + + + + org.apache.tuscany.sca + tuscany-workspace + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-workspace-xml + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-implementation-node + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-implementation-node-runtime + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-binding-atom + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-workspace-impl + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-node-api + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-core + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-node-impl + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-data-api + 1.6.1 + + + + commons-fileupload + commons-fileupload + 1.2 + + + + xerces + xercesImpl + 2.8.1 + + + + javax.servlet + servlet-api + 2.5 + provided + + + + org.apache.tuscany.sca + tuscany-host-jetty + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-node-manager + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-contribution-xml + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-contribution-resource + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-contribution-java + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-contribution-namespace + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-domain-search + 1.6.1 + + + + org.apache.tuscany.sca + tuscany-implementation-java-runtime + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-implementation-widget-runtime-tuscany + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-binding-atom-abdera + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-binding-atom-js + 1.6.1 + runtime + + + + commons-lang + commons-lang + 2.3 + + + + org.apache.tuscany.sca + tuscany-binding-http-runtime + 1.6.1 + runtime + + + + org.apache.tuscany.sca + tuscany-monitor + 1.6.1 + + + + + + + + + org.apache.felix + maven-bundle-plugin + + + + ${tuscany.version} + org.apache.tuscany.sca.domain.manager + ${pom.name} + org.apache.tuscany.sca.domain.manager* + + + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationCollectionImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationCollectionImpl.java new file mode 100644 index 0000000000..0e25068f5f --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationCollectionImpl.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeTitle; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.contributionURI; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a component that returns composite configuration collections. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={ItemCollection.class, LocalItemCollection.class}) +public class CompositeConfigurationCollectionImpl implements ItemCollection, LocalItemCollection { + + private static final Logger logger = Logger.getLogger(CompositeConfigurationCollectionImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public LocalItemCollection cloudCollection; + + /** + * Initialize the component. + */ + @Init + public void initialize() { + } + + public Entry[] getAll() { + throw new UnsupportedOperationException(); + } + + public Item get(String key) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public String post(String key, Item item) { + throw new UnsupportedOperationException(); + } + + public void put(String key, Item item) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public void delete(String key) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public Entry[] query(String queryString) { + logger.fine("query " + queryString); + + if (queryString.startsWith("composite=")) { + + // Expecting a key in the form: + // composite:contributionURI;namespace;localName + int e = queryString.indexOf('='); + String key = queryString.substring(e + 1); + String contributionURI = contributionURI(key); + QName qname = compositeQName(key); + + // Return a collection containing the following entries: + // the resolved version of the specified composite + // the required contributions + List> entries = new ArrayList>(); + + // Add the resolved composite entry + Entry compositeEntry = new Entry(); + Item compositeItem = new Item(); + compositeItem.setTitle(compositeTitle(contributionURI, qname)); + compositeItem.setLink("/composite-resolved/" + key); + compositeEntry.setKey(key); + compositeEntry.setData(compositeItem); + entries.add(compositeEntry); + + // Get the collection of required contributions + Entry[] contributionEntries = contributionCollection.query("alldependencies=" + contributionURI); + for (Entry entry: contributionEntries) { + Item item = entry.getData(); + item.setContents(null); + entries.add(entry); + } + + return entries.toArray(new Entry[entries.size()]); + + } else { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationServiceImpl.java new file mode 100644 index 0000000000..4178a2e8a0 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeConfigurationServiceImpl.java @@ -0,0 +1,657 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.contributionURI; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.locationURL; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.TransformerFactory; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.SCABindingFactory; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilder; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; +import org.apache.tuscany.sca.assembly.builder.impl.CompositeBuilderImpl; +import org.apache.tuscany.sca.assembly.builder.impl.CompositeIncludeBuilderImpl; +import org.apache.tuscany.sca.assembly.xml.CompositeDocumentProcessor; +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.apache.tuscany.sca.definitions.SCADefinitions; +import org.apache.tuscany.sca.definitions.impl.SCADefinitionsImpl; +import org.apache.tuscany.sca.definitions.util.SCADefinitionsUtil; +import org.apache.tuscany.sca.implementation.node.NodeImplementation; +import org.apache.tuscany.sca.implementation.node.builder.impl.NodeCompositeBuilderImpl; +import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.MonitorRuntimeException; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentAttachPointType; +import org.apache.tuscany.sca.policy.IntentAttachPointTypeFactory; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.provider.SCADefinitionsProvider; +import org.apache.tuscany.sca.provider.SCADefinitionsProviderExtensionPoint; +import org.apache.tuscany.sca.workspace.Workspace; +import org.apache.tuscany.sca.workspace.WorkspaceFactory; +import org.apache.tuscany.sca.workspace.builder.ContributionDependencyBuilder; +import org.apache.tuscany.sca.workspace.builder.impl.ContributionDependencyBuilderImpl; +import org.apache.tuscany.sca.workspace.processor.impl.ContributionContentProcessor; +import org.osoa.sca.ServiceRuntimeException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a service that returns a fully configured composite. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(Servlet.class) +public class CompositeConfigurationServiceImpl extends HttpServlet implements Servlet { + private static final long serialVersionUID = -8809641932774129152L; + + private static final Logger logger = Logger.getLogger(CompositeConfigurationServiceImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public LocalItemCollection domainCompositeCollection; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + @Reference + public LocalItemCollection cloudCollection; + + private ExtensionPointRegistry extensionPoints; + private ModelFactoryExtensionPoint modelFactories; + private ModelResolverExtensionPoint modelResolvers; + private AssemblyFactory assemblyFactory; + private WorkspaceFactory workspaceFactory; + private URLArtifactProcessor contributionProcessor; + private StAXArtifactProcessorExtensionPoint staxProcessors; + private StAXArtifactProcessor compositeProcessor; + private XMLOutputFactory outputFactory; + private ContributionDependencyBuilder contributionDependencyBuilder; + private CompositeBuilder compositeIncludeBuilder; + private CompositeBuilder nodeConfigurationBuilder; + private Monitor monitor; + private List policyDefinitions; + private ModelResolver policyDefinitionsResolver; + private SCABindingFactory scaBindingFactory; + private IntentAttachPointTypeFactory intentAttachPointTypeFactory; + private DocumentBuilderFactory documentBuilderFactory; + private TransformerFactory transformerFactory; + private InterfaceContractMapper contractMapper; + private Map bindingMap; + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + + extensionPoints = domainManagerConfiguration.getExtensionPoints(); + + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + monitor = monitorFactory.createMonitor(); + + // Get model factories + modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true); + workspaceFactory = modelFactories.getFactory(WorkspaceFactory.class); + + // Get and initialize artifact processors + staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + compositeProcessor = (StAXArtifactProcessor)staxProcessors.getProcessor(Composite.class); + StAXArtifactProcessor staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, monitor); + + URLArtifactProcessorExtensionPoint urlProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + URLArtifactProcessor urlProcessor = new ExtensibleURLArtifactProcessor(urlProcessors, monitor); + policyDefinitionsResolver = new DefaultModelResolver(); + policyDefinitions = new ArrayList(); + + // The following was copied from RuntimeBuilder to fix TUSCANY-3171 + XMLInputFactory validatingInputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class); + documentBuilderFactory = modelFactories.getFactory(DocumentBuilderFactory.class); + //documentBuilderFactory.setNamespaceAware(true); + urlProcessors.getProcessor(Composite.class); + urlProcessors.addArtifactProcessor(new CompositeDocumentProcessor(staxProcessor, validatingInputFactory, + documentBuilderFactory, policyDefinitions, monitor)); + + // Create contribution processor + modelResolvers = extensionPoints.getExtensionPoint(ModelResolverExtensionPoint.class); + contributionProcessor = new ContributionContentProcessor(extensionPoints, monitor, policyDefinitionsResolver, policyDefinitions); + + // Create contribution and composite builders + transformerFactory = modelFactories.getFactory(TransformerFactory.class); + contributionDependencyBuilder = new ContributionDependencyBuilderImpl(monitor); + scaBindingFactory = modelFactories.getFactory(SCABindingFactory.class); + intentAttachPointTypeFactory = modelFactories.getFactory(IntentAttachPointTypeFactory.class); + contractMapper = utilities.getUtility(InterfaceContractMapper.class); + compositeIncludeBuilder = new CompositeIncludeBuilderImpl(monitor); + bindingMap = new HashMap(); + nodeConfigurationBuilder = new NodeCompositeBuilderImpl(assemblyFactory, scaBindingFactory, documentBuilderFactory, + transformerFactory, contractMapper, null, monitor, bindingMap); + + // Load the definitions.xml + loadSCADefinitions(extensionPoints); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + String key; + if (path.startsWith("/")) { + if (path.length() > 1) { + key = path.substring(1); + } else { + key =""; + } + } else { + key =path; + } + logger.fine("get " + key); + + // Expect a key in the form composite:contributionURI;namespace;localName or + // a path in the form componentName/componentName/... + // and return the corresponding resolved composite + String requestedContributionURI = null; + QName requestedCompositeName = null; + String[] requestedComponentPath = null; + if (key.startsWith("composite:")) { + + // Extract the composite qname from the key + requestedContributionURI = contributionURI(key); + requestedCompositeName = compositeQName(key); + + } else if (key.length() != 0) { + + // Extract the path to the requested component from the key + requestedComponentPath = key.split("/"); + } + + // Somewhere to store the composite we expect to write out at the end + Composite requestedComposite = null; + + // Create a domain composite model + Composite domainComposite = assemblyFactory.createComposite(); + domainComposite.setName(new QName(Constants.SCA10_TUSCANY_NS, "domain")); + + // Get the domain composite items + Entry[] domainEntries = domainCompositeCollection.getAll(); + + // Populate the domain composite + Workspace workspace = workspaceFactory.createWorkspace(); + workspace.setModelResolver(new ExtensibleModelResolver(workspace, extensionPoints)); + + Map contributionMap = new HashMap(); + for (Entry domainEntry: domainEntries) { + + // Load the required contributions + String contributionURI = contributionURI(domainEntry.getKey()); + Contribution contribution = contributionMap.get(contributionURI); + if (contribution == null) { + + // The contribution has not been loaded yet, load it with all its dependencies + Entry[] entries = contributionCollection.query("alldependencies=" + contributionURI); + for (Entry entry: entries) { + Item dependencyItem = entry.getData(); + String dependencyURI = entry.getKey(); + + if (!contributionMap.containsKey(dependencyURI)) { + + // Read the contribution + Contribution dependency; + try { + String dependencyLocation = dependencyItem.getAlternate(); + dependency = contribution(workspace, dependencyURI, dependencyLocation); + } catch (Exception e) { + if (contributionURI.equals(dependencyURI)) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, getDescription(e)); + return; + } else { + continue; + } + } + workspace.getContributions().add(dependency); + contributionMap.put(dependencyURI, dependency); + + if (contributionURI.equals(entry.getKey())) { + contribution = dependency; + } + } + } + } + + if (contribution == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, contributionURI); + return; + } + + // Find the specified deployable composite in the contribution + Composite deployable = null; + QName qn = compositeQName(domainEntry.getKey()); + for (Composite d: contribution.getDeployables()) { + if (qn.equals(d.getName())) { + deployable = d; + break; + } + } + if (deployable == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, qn.toString()); + return; + } + + // add the deployable composite to the domain composite + domainComposite.getIncludes().add(deployable); + + // Fuse includes into the deployable composite + try { + compositeIncludeBuilder.build(deployable); + analyzeProblems(); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, getDescription(e)); + return; + } + + // Store away the requested composite + if (requestedCompositeName != null) { + if (requestedContributionURI.equals(contributionURI) && requestedCompositeName.equals(deployable.getName())){ + requestedComposite = deployable; + } + } + } + + // The requested composite was not found + if (requestedCompositeName != null && requestedComposite == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + // Get the clouds composite + Composite cloudsComposite; + try { + cloudsComposite = cloud(); + } catch (NotFoundException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage()); + return; + } + + // configure the endpoints for each composite in the domain + List domainIncludes = domainComposite.getIncludes(); + for (int i = 0, n =domainIncludes.size(); i < n; i++) { + Composite composite = domainIncludes.get(i); + QName compositeName = composite.getName(); + String contributionURI = contributionURI(domainEntries[i].getKey()); + + // find the node that will run this composite and the default + // bindings that it configures + Component nodeComponent = null; + QName nodeCompositeName = null; + for (Composite cloudComposite : cloudsComposite.getIncludes()) { + for (Component nc : cloudComposite.getComponents()) { + NodeImplementation nodeImplementation = (NodeImplementation)nc.getImplementation(); + if (nodeImplementation.getComposite().getName().equals(compositeName) && + nodeImplementation.getComposite().getURI().equals(contributionURI)) { + nodeImplementation.setComposite(composite); + nodeComponent = nc; + nodeCompositeName = cloudComposite.getName(); + break; + } + } + } + + if (nodeComponent != null) { + try { + Composite nodeComposite = assemblyFactory.createComposite(); + nodeComposite.setName(nodeCompositeName); + nodeComposite.getComponents().add(nodeComponent); + nodeConfigurationBuilder.build(nodeComposite); + } catch (CompositeBuilderException e) { + throw new ServletException(e); + } + } + } + + // Build the domain composite + SCADefinitions aggregatedDefinitions = new SCADefinitionsImpl(); + for (SCADefinitions definition : policyDefinitions) { + SCADefinitionsUtil.aggregateSCADefinitions(definition, aggregatedDefinitions); + } + CompositeBuilder compositeBuilder = new CompositeBuilderImpl(assemblyFactory, null, scaBindingFactory, + intentAttachPointTypeFactory, documentBuilderFactory, transformerFactory, + contractMapper, aggregatedDefinitions, monitor, bindingMap); + try { + compositeBuilder.build(domainComposite); + analyzeProblems(); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, getDescription(e)); + return; + } + + // Return the requested composite + if (requestedComposite != null) { + + // Rebuild the requested composite from the domain composite + // we have to reverse the flattening that went on when the domain + // composite was built + List tempComponentList = new ArrayList(); + tempComponentList.addAll(requestedComposite.getComponents()); + requestedComposite.getComponents().clear(); + for (Component inputComponent : tempComponentList){ + for (Component deployComponent : domainComposite.getComponents()){ + if (deployComponent.getName().equals(inputComponent.getName())){ + requestedComposite.getComponents().add(deployComponent); + } + } + } + + } else if (requestedComponentPath != null) { + + // If a component path was specified, walk the path to get to the requested + // component and the composite that implements it + Composite nestedComposite = domainComposite; + for (String componentName: requestedComponentPath) { + Component component = null; + for (Component c: nestedComposite.getComponents()) { + if (componentName.equals(c.getName())) { + component = c; + break; + } + } + if (component == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } else { + if (component.getImplementation() instanceof Composite) { + nestedComposite = (Composite)component.getImplementation(); + } else { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + } + } + + // Return the nested composite + requestedComposite = nestedComposite; + + } else { + + + // Return the whole domain composite + requestedComposite = domainComposite; + } + + // Write the composite in the requested format + StAXArtifactProcessor processor; + String queryString = request.getQueryString(); + if (queryString != null && queryString.startsWith("format=")) { + String format = queryString.substring(7); + int s = format.indexOf(';'); + QName formatName = new QName(format.substring(0, s), format.substring(s +1)); + processor = (StAXArtifactProcessor)staxProcessors.getProcessor(formatName); + if (processor == null) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, new IllegalArgumentException(queryString).toString()); + return; + } + } else { + processor = compositeProcessor; + } + try { + response.setContentType("text/xml"); + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(response.getOutputStream()); + processor.write(requestedComposite, writer); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); + return; + } + + + } + + /** + * Returns the cloud composite. + * + * @return the cloud composite + */ + private Composite cloud() throws NotFoundException { + + // Create a new composite for the clouds + Composite cloudComposite = assemblyFactory.createComposite(); + cloudComposite.setName(new QName(Constants.SCA10_TUSCANY_NS, "cloud")); + + // Get the collection of cloud composites + Entry[] cloudEntries = cloudCollection.getAll(); + + // Load the cloud contributions + Workspace workspace = workspaceFactory.createWorkspace(); + Map contributionMap = new HashMap(); + for (Entry cloudEntry: cloudEntries) { + String key = cloudEntry.getKey(); + String contributionURI = contributionURI(key); + + // Load the contribution + Contribution contribution = contributionMap.get(contributionURI); + if (contribution == null) { + Item contributionItem = contributionCollection.get(contributionURI); + + // Read the contribution + try { + contribution = contribution(workspace, contributionURI, contributionItem.getAlternate()); + } catch (ContributionReadException e) { + continue; + } + workspace.getContributions().add(contribution); + contributionMap.put(contributionURI, contribution); + + } + + // Include the cloud composite in the clouds composite + QName qname = compositeQName(key); + for (Artifact artifact : contribution.getArtifacts()) { + if (artifact.getModel() instanceof Composite) { + Composite composite = (Composite)artifact.getModel(); + if (composite.getName().equals(qname)) { + cloudComposite.getIncludes().add(composite); + } + } + } + } + + return cloudComposite; + } + + /** + * Returns the contribution with the given URI. + * + * @param workspace + * @param contributionURI + * @param contributionLocation + * @return + * @throws NotFoundException + */ + private Contribution contribution(Workspace workspace, String contributionURI, String contributionLocation) throws ContributionReadException { + try { + URI uri = URI.create(contributionURI); + URL location = locationURL(contributionLocation); + + Contribution contribution = (Contribution)contributionProcessor.read(null, uri, location); + try { + analyzeProblems(); + } catch (ServiceRuntimeException e) { + throw e; + } catch (Exception e) { + throw new ContributionReadException(e); + } + + // Resolve the contribution dependencies + contributionDependencyBuilder.buildContributionDependencies(contribution, workspace); + + contributionProcessor.resolve(contribution, workspace.getModelResolver()); + try { + analyzeProblems(); + } catch (ServiceRuntimeException e) { + throw e; + } catch (Exception e) { + throw new ContributionReadException(e); + } + return contribution; + + } catch (ContributionReadException e) { + throw e; + } catch (ContributionResolveException e) { + throw new ContributionReadException(e); + } catch (MalformedURLException e) { + throw new ContributionReadException(e); + } + } + + private void analyzeProblems() throws Exception { + + for (Problem problem : monitor.getProblems()) { + if ((problem.getSeverity() == Severity.ERROR) && (!problem.getMessageId().equals("SchemaError"))) { + if (problem.getCause() != null) { + throw new ServiceRuntimeException(new MonitorRuntimeException(problem.getCause())); + } else { + throw new ServiceRuntimeException(new MonitorRuntimeException(problem.toString())); + } + } + } + } + + private String getDescription(Exception e) { + if (e instanceof ServiceRuntimeException && e.getCause() instanceof MonitorRuntimeException) { + Throwable ce = e.getCause(); + return ce.getCause() != null ? ce.getCause().toString() : ce.getMessage(); + } else { + return e.toString(); + } + } + + + /** + * The following code was copied from RuntimeBootStrapper to fix TUSCANY-3171 + * + * @param registry + */ + private void loadSCADefinitions(ExtensionPointRegistry registry) throws ParserConfigurationException { + try { + URLArtifactProcessorExtensionPoint documentProcessors = + registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + URLArtifactProcessor definitionsProcessor = + documentProcessors.getProcessor(SCADefinitions.class); + SCADefinitionsProviderExtensionPoint scaDefnProviders = + registry.getExtensionPoint(SCADefinitionsProviderExtensionPoint.class); + + SCADefinitions systemSCADefinitions = new SCADefinitionsImpl(); + SCADefinitions aSCADefn = null; + for (SCADefinitionsProvider aProvider : scaDefnProviders.getSCADefinitionsProviders()) { + aSCADefn = aProvider.getSCADefinition(); + SCADefinitionsUtil.aggregateSCADefinitions(aSCADefn, systemSCADefinitions); + } + + policyDefinitions.add(systemSCADefinitions); + + //we cannot expect that providers will add the intents and policysets into the resolver + //so we do this here explicitly + for (Intent intent : systemSCADefinitions.getPolicyIntents()) { + policyDefinitionsResolver.addModel(intent); + } + + for (PolicySet policySet : systemSCADefinitions.getPolicySets()) { + policyDefinitionsResolver.addModel(policySet); + } + + for (IntentAttachPointType attachPoinType : systemSCADefinitions.getBindingTypes()) { + policyDefinitionsResolver.addModel(attachPoinType); + } + + for (IntentAttachPointType attachPoinType : systemSCADefinitions.getImplementationTypes()) { + policyDefinitionsResolver.addModel(attachPoinType); + } + + //now that all system sca definitions have been read, lets resolve them right away + definitionsProcessor.resolve(systemSCADefinitions, policyDefinitionsResolver); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeGeneratorServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeGeneratorServiceImpl.java new file mode 100644 index 0000000000..c476d82e72 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/CompositeGeneratorServiceImpl.java @@ -0,0 +1,255 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.contributionURI; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.lastModified; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.locationURL; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.apache.tuscany.sca.domain.manager.impl.CompositeGeneratorServiceImpl.Cache.ContributionCache; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.workspace.processor.impl.ContributionContentProcessor; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a service that generates a composite from a composite model. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={Servlet.class}) +public class CompositeGeneratorServiceImpl extends HttpServlet implements Servlet { + private static final long serialVersionUID = -6531448326726908269L; + + private static final Logger logger = Logger.getLogger(CompositeGeneratorServiceImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + private ModelFactoryExtensionPoint modelFactories; + private ModelResolverExtensionPoint modelResolvers; + private URLArtifactProcessor contributionProcessor; + private StAXArtifactProcessor compositeProcessor; + private XMLOutputFactory outputFactory; + + /** + * Cache contribution models. + */ + static class Cache { + static class ContributionCache { + private Contribution contribution; + private long contributionLastModified; + } + private Map contributions = new HashMap(); + } + + private Cache cache = new Cache(); + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + + ExtensionPointRegistry extensionPoints = domainManagerConfiguration.getExtensionPoints(); + + // Create a monitor + UtilityExtensionPoint services = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = services.getUtility(MonitorFactory.class); + Monitor monitor = monitorFactory.createMonitor(); + + // Get model factories + modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true); + + // Get and initialize artifact processors + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + compositeProcessor = (StAXArtifactProcessor)staxProcessors.getProcessor(Composite.class); + StAXArtifactProcessor staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, monitor); + + URLArtifactProcessorExtensionPoint urlProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + URLArtifactProcessor urlProcessor = new ExtensibleURLArtifactProcessor(urlProcessors, monitor); + + // Create contribution processor + modelResolvers = extensionPoints.getExtensionPoint(ModelResolverExtensionPoint.class); + contributionProcessor = new ContributionContentProcessor(extensionPoints, monitor); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // Expect a key in the form + // composite:contributionURI;namespace;localName + // and return the corresponding source file + + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + String key = path.startsWith("/")? path.substring(1) : path; + logger.fine("get " + key); + + // Get the specified contribution info + String contributionURI = contributionURI(key); + Item contributionItem; + try { + contributionItem = contributionCollection.get(contributionURI); + } catch (NotFoundException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + // Read the contribution + Contribution contribution; + try { + contribution = contribution(contributionURI, contributionItem.getAlternate()); + } catch (ContributionReadException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + // Find the specified deployable composite + QName qname = compositeQName(key); + Composite composite = null; + for (Composite deployable: contribution.getDeployables()) { + if (qname.equals(deployable.getName())) { + if (!deployable.isUnresolved()) { + composite = deployable; + } + break; + } + } + if (composite == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + // Write the composite + response.setContentType("text/xml"); + ServletOutputStream os = response.getOutputStream(); + try { + compositeProcessor.write(composite, outputFactory.createXMLStreamWriter(os)); + } catch (ContributionWriteException e) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); + return; + } catch (XMLStreamException e) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); + return; + } + os.flush(); + } + + /** + * Returns the contribution with the given URI. + * + * @param contributionURI + * @param contributionLocation + * @return + * @throws NotFoundException + */ + private Contribution contribution(String contributionURI, String contributionLocation) throws ContributionReadException { + try { + URI uri = URI.create(contributionURI); + URL location = locationURL(contributionLocation); + + // Get contribution from cache + ContributionCache contributionCache = cache.contributions.get(location); + long lastModified = lastModified(location); + if (contributionCache != null) { + if (contributionCache.contributionLastModified == lastModified) { + return contributionCache.contribution; + } + + // Reset contribution cache + cache.contributions.remove(location); + } + + Contribution contribution = (Contribution)contributionProcessor.read(null, uri, location); + + contributionProcessor.resolve(contribution, new DefaultModelResolver()); + + // Cache contribution + contributionCache = new ContributionCache(); + contributionCache.contribution = contribution; + contributionCache.contributionLastModified = lastModified; + cache.contributions.put(location, contributionCache); + + return contribution; + + } catch (ContributionReadException e) { + throw e; + } catch (MalformedURLException e) { + throw new ContributionReadException(e); + } catch (IOException e) { + throw new ContributionReadException(e); + } catch (ContributionResolveException e) { + throw new ContributionReadException(e); + } + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionCollectionImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionCollectionImpl.java new file mode 100644 index 0000000000..3e17ae007b --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionCollectionImpl.java @@ -0,0 +1,705 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.DEPLOYMENT_CONTRIBUTION_URI; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeSimpleTitle; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeSourceLink; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.lastModified; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.locationURL; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.DefaultExport; +import org.apache.tuscany.sca.contribution.DefaultImport; +import org.apache.tuscany.sca.contribution.Export; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.apache.tuscany.sca.domain.manager.impl.ContributionCollectionImpl.Cache.ContributionCache; +import org.apache.tuscany.sca.domain.search.DomainSearch; +import org.apache.tuscany.sca.domain.search.IndexException; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.monitor.impl.ProblemImpl; +import org.apache.tuscany.sca.workspace.Workspace; +import org.apache.tuscany.sca.workspace.WorkspaceFactory; +import org.apache.tuscany.sca.workspace.builder.ContributionDependencyBuilder; +import org.apache.tuscany.sca.workspace.builder.impl.ContributionDependencyBuilderImpl; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.osoa.sca.ServiceRuntimeException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Document; + +/** + * Implementation of a contribution collection service component. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={ItemCollection.class, LocalItemCollection.class}) +public class ContributionCollectionImpl implements ItemCollection, LocalItemCollection { + + private static final Logger logger = Logger.getLogger(ContributionCollectionImpl.class.getName()); + + @Property + public String workspaceFile; + + @Property + public String deploymentContributionDirectory; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + @Reference + public DomainSearch domainSearch; + + private Monitor monitor; + private ContributionFactory contributionFactory; + private WorkspaceFactory workspaceFactory; + private StAXArtifactProcessor staxProcessor; + private URLArtifactProcessor contributionProcessor; + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private DocumentBuilder documentBuilder; + + /** + * Cache workspace and contribution models. + */ + static class Cache { + private Workspace workspace; + private long workspaceLastModified; + + static class ContributionCache { + private Contribution contribution; + private long contributionLastModified; + } + private Map contributions = new HashMap(); + } + + private Cache cache = new Cache(); + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + + ExtensionPointRegistry extensionPoints = domainManagerConfiguration.getExtensionPoints(); + + // Create a validation monitor + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + monitor = monitorFactory.createMonitor(); + + // Create model factories + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true); + contributionFactory = modelFactories.getFactory(ContributionFactory.class); + workspaceFactory = modelFactories.getFactory(WorkspaceFactory.class); + + // Create artifact processors + inputFactory = modelFactories.getFactory(XMLInputFactory.class); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, monitor); + + URLArtifactProcessorExtensionPoint urlProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + + // Create contribution info processor + contributionProcessor = urlProcessors.getProcessor(".contribution/info"); + + // Create a document builder (used to pretty print XML) + documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + public Entry[] getAll() { + logger.fine("getAll"); + + // Return all the contributions + List> entries = new ArrayList>(); + Workspace workspace = readContributions(readWorkspace()); + + for (Contribution contribution: workspace.getContributions()) { + if (contribution.getURI().equals(DEPLOYMENT_CONTRIBUTION_URI)) { + continue; + } + entries.add(entry(workspace, contribution)); + } + return entries.toArray(new Entry[entries.size()]); + } + + public Item get(String key) throws NotFoundException { + logger.fine("get " + key); + + // Returns the contribution with the given URI key + Workspace workspace = readContributions(readWorkspace()); + for (Contribution contribution: workspace.getContributions()) { + if (key.equals(contribution.getURI())) { + return item(workspace, contribution); + } + } + throw new NotFoundException(key); + } + + public String post(String key, Item item) { + logger.fine("post " + key); + + // Adds a new contribution to the workspace + Workspace workspace = readWorkspace(); + Contribution contribution = contributionFactory.createContribution(); + contribution.setURI(key); + try { + contribution.setLocation(locationURL(item.getLink()).toString()); + } catch (MalformedURLException e) { + throw new ServiceRuntimeException(e); + } + workspace.getContributions().add(contribution); + + // Write the workspace + writeWorkspace(workspace); + + // add it to the search index, contributionUpdated is called to guarantee + // only one contribution with the same URI in the index + if (domainSearch != null) { // can be null in unit tests + + try { + domainSearch.updateContribution(contribution, contribution); + + } catch (IndexException e) { + logger.warning("Could not update contribution on index: " + contribution.getURI()); + } + + } + + return key; + + } + + public void put(String key, Item item) throws NotFoundException { + + // Update a contribution already in the workspace + Workspace workspace = readWorkspace(); + Contribution newContribution = contributionFactory.createContribution(); + newContribution.setURI(key); + try { + newContribution.setLocation(locationURL(item.getLink()).toString()); + } catch (MalformedURLException e) { + throw new ServiceRuntimeException(e); + } + List contributions = workspace.getContributions(); + for (int i = 0, n = contributions.size(); i < n; i++) { + if (contributions.get(i).getURI().equals(key)) { + contributions.set(i, newContribution); + + // Write the workspace + writeWorkspace(workspace); + return; + } + } + throw new NotFoundException(key); + } + + public void delete(String key) throws NotFoundException { + logger.fine("delete " + key); + + // Delete a contribution from the workspace + Workspace workspace = readWorkspace(); + List contributions = workspace.getContributions(); + for (int i = 0, n = contributions.size(); i < n; i++) { + + Contribution contribution = contributions.get(i); + + if (contribution.getURI().equals(key)) { + contributions.remove(i); + + // Write the workspace + writeWorkspace(workspace); + + // delete it from the search index + if (domainSearch != null) { // can be null in unit tests + + try { + domainSearch.removeContribution(contribution); + } catch (IndexException e) { + logger.warning("Could not remove contribution from index: " + contribution.getURI()); + } + + } + + return; + + } + } + throw new NotFoundException(key); + } + + public Entry[] query(String queryString) { + logger.fine("query " + queryString); + + if (queryString.startsWith("dependencies=") || queryString.startsWith("alldependencies=")) { + + // Return the collection of dependencies of the specified contribution + List> entries = new ArrayList>(); + + // Extract the contribution URI + int eq = queryString.indexOf('='); + String key = queryString.substring(eq+1); + + // Read the metadata for all the contributions + Workspace workspace = readContributions(readWorkspace()); + + // Look for the specified contribution + for (Contribution contribution: workspace.getContributions()) { + if (key.equals(contribution.getURI())) { + + // Compute the contribution dependencies + ContributionDependencyBuilder analyzer = new ContributionDependencyBuilderImpl(monitor); + List dependencies = analyzer.buildContributionDependencies(contribution, workspace); + + // Returns entries for the dependencies + // optionally skip the specified contribution + boolean allDependencies = queryString.startsWith("alldependencies="); + for (Contribution dependency: dependencies) { + if (!allDependencies && dependency == contribution) { + // Skip the specified contribution + continue; + } + entries.add(entry(workspace, dependency)); + } + break; + } + } + + return entries.toArray(new Entry[entries.size()]); + + } if (queryString.startsWith("suggestions=true")) { + + // Returns a list of contribution suggestions, scan the parent of the workspace + // directory for potential contribution directories + + // For now, recognize project directories that contain .project files + // Directories containing .classpath files are likely to be Java projects, we parse + // the .classpath file to determine the Java project output location + Workspace suggestionWorkspace = workspaceFactory.createWorkspace(); + List entries = new ArrayList(); + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + File rootLocation = new File(new File(rootDirectory).toURI().normalize()); + for (File project: rootLocation.getParentFile().listFiles()) { + File dotProject = new File(project, ".project"); + if (!dotProject.exists()) { + continue; + } + + // We have a potential contribution + String uri = project.getName(); + File location = project; + + // If this is a Java project, parse its .classpath file to determine it's output location + File dotClasspath = new File(project, ".classpath"); + if (dotClasspath.exists()) { + try { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new FileInputStream(dotClasspath)); + reader.nextTag(); + while (reader.hasNext()) { + int event = reader.getEventType(); + if (event == START_ELEMENT) { + if ("classpathentry".equals(reader.getName().getLocalPart())) { + if ("output".equals(reader.getAttributeValue("", "kind"))) { + location = new File(project, reader.getAttributeValue("", "path")); + break; + } + } + } + if (reader.hasNext()) { + reader.next(); + } + } + } catch (FileNotFoundException e) { + } catch (XMLStreamException e) { + } + + } + + // Create a contribution entry, skip the domain root directory and childrens of the + // domain root directory + String rootLocationPath = rootLocation.getPath(); + if (rootLocationPath.indexOf('\\') != -1 || rootLocationPath.indexOf(' ') != -1) { + rootLocationPath = new File(rootLocationPath.replace('\\', '/')).toURI().toString(); + } + String locationPath = location.getPath(); + if (locationPath.indexOf('\\') != -1 || locationPath.indexOf(' ') != -1) { + locationPath = new File(locationPath.replace('\\', '/')).toURI().toString(); + } + if (!locationPath.startsWith(rootLocationPath + "/") && !locationPath.equals(rootLocationPath)) { + Contribution contribution = contributionFactory.createContribution(); + contribution.setURI(uri); + contribution.setLocation(locationPath); + entries.add(entry(suggestionWorkspace, contribution)); + } + } + + return entries.toArray(new Entry[entries.size()]); + + } else { + throw new UnsupportedOperationException(); + } + } + + /** + * Returns an entry representing a contribution + * @param contribution + * @return + */ + private static Entry entry(Workspace workspace, Contribution contribution) { + Entry entry = new Entry(); + entry.setKey(contribution.getURI()); + entry.setData(item(workspace, contribution)); + return entry; + } + + /** + * Returns an item representing a contribution. + * + * @param contribution + * @return + */ + private static Item item(Workspace workspace, Contribution contribution) { + String contributionURI = contribution.getURI(); + Item item = new Item(); + item.setTitle(title(contributionURI)); + item.setLink(link(contributionURI)); + item.setAlternate(contribution.getLocation()); + + // List the contribution dependencies in the item contents + final List problems = new ArrayList(); + Monitor monitor = new Monitor() { + public void problem(Problem problem) { + problems.add(problem.getMessageId() + " " + problem.getProblemObject().toString()); + } + + public List getProblems() { + return null; + } + public Problem createProblem(String sourceClassName, String bundleName, + Severity severity, Object problemObject, String messageId, + Exception cause) { + return new ProblemImpl(sourceClassName, bundleName, severity, + problemObject, messageId, cause); + } + + public Problem createProblem(String sourceClassName, String bundleName, + Severity severity, Object problemObject, String messageId, + Object... messageParams) { + return new ProblemImpl(sourceClassName, bundleName, severity, + problemObject, messageId, messageParams); + } + }; + + StringBuffer sb = new StringBuffer(); + ContributionDependencyBuilderImpl analyzer = new ContributionDependencyBuilderImpl(monitor); + List dependencies = analyzer.buildContributionDependencies(contribution, workspace); + if (dependencies.size() > 1) { + sb.append("Dependencies: "); + for (int i = 0, n = dependencies.size(); i < n ; i++) { + if (i > 0) { + sb.append(" "); + } + Contribution dependency = dependencies.get(i); + if (dependency != contribution) { + String dependencyURI = dependency.getURI(); + sb.append("" + title(dependencyURI) + ""); + } + } + sb.append("
"); + } + + // List the deployables + List deployables = contribution.getDeployables(); + if (!deployables.isEmpty()) { + sb.append("Deployables: "); + for (int i = 0, n = deployables.size(); i < n ; i++) { + if (i > 0) { + sb.append(" "); + } + Composite deployable = deployables.get(i); + QName qname = deployable.getName(); + sb.append("" + compositeSimpleTitle(contributionURI, qname) + ""); + } + sb.append("
"); + } + + // List the dependency problems + if (contribution.isUnresolved()) { + problems.add("Contribution not found"); + } + if (problems.size() > 0) { + sb.append(""); + for (int i = 0, n = problems.size(); i < n ; i++) { + sb.append("Problem: "+ problems.get(i) + "
"); + } + sb.append("
"); + } + + // Store in the item contents + item.setContents(sb.toString()); + + return item; + } + + /** + * Returns a link to a contribution. + * @param contributionURI + * @return + */ + private static String link(String contributionURI) { + return "/contribution/" + contributionURI; + } + + /** + * Returns a title for the given contribution + * + * @param contributionURI + * @return + */ + private static String title(String contributionURI) { + return contributionURI; + } + + /** + * Read the workspace. + * + * @return + */ + Workspace readWorkspace() { + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + Workspace workspace; + File file = new File(rootDirectory + "/" + workspaceFile); + if (file.exists()) { + + // Get workspace from cache + if (cache.workspace != null && file.lastModified() == cache.workspaceLastModified) { + workspace = cache.workspace; + + } else { + + try { + FileInputStream is = new FileInputStream(file); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + reader.nextTag(); + workspace = (Workspace)staxProcessor.read(reader); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + // Cache workspace + cache.workspaceLastModified = file.lastModified(); + cache.workspace = workspace; + } + + } else { + + // Create new workspace + workspace = workspaceFactory.createWorkspace(); + + // Cache workspace + cache.workspaceLastModified = 0; + cache.workspace = workspace; + } + + // Make sure that the workspace contains the cloud contribution + // The cloud contribution contains the composites describing the + // SCA nodes declared in the cloud + Contribution cloudContribution = null; + for (Contribution contribution: workspace.getContributions()) { + if (contribution.getURI().equals(DEPLOYMENT_CONTRIBUTION_URI)) { + cloudContribution = contribution; + } + } + if (cloudContribution == null) { + Contribution contribution = contributionFactory.createContribution(); + contribution.setURI(DEPLOYMENT_CONTRIBUTION_URI); + File cloudDirectory = new File(rootDirectory + "/" + deploymentContributionDirectory); + contribution.setLocation(cloudDirectory.toURI().toString()); + workspace.getContributions().add(contribution); + } + + return workspace; + } + + /** + * Write the workspace back to disk + * + * @param workspace + */ + private void writeWorkspace(Workspace workspace) { + try { + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + // First write to a byte stream + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(bos); + staxProcessor.write(workspace, writer); + + // Parse again to pretty format the document + Document document = documentBuilder.parse(new ByteArrayInputStream(bos.toByteArray())); + OutputFormat format = new OutputFormat(); + format.setIndenting(true); + format.setIndent(2); + + // Write to workspace.xml + File file = new File(rootDirectory + "/" + workspaceFile); + FileOutputStream os = new FileOutputStream(file); + XMLSerializer serializer = new XMLSerializer(os, format); + serializer.serialize(document); + os.close(); + + // Cache workspace + cache.workspace = workspace; + cache.workspaceLastModified = file.lastModified(); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + /** + * Returns a workspace populated with the contribution info read from + * the contributions. + * + * @param workspace + * @return + */ + private Workspace readContributions(Workspace workspace) { + + Workspace contributions = workspaceFactory.createWorkspace(); + try { + for (Contribution c: workspace.getContributions()) { + URI uri = URI.create(c.getURI()); + URL location = locationURL(c.getLocation()); + + // Get contribution from cache + ContributionCache contributionCache = cache.contributions.get(location); + long lastModified = lastModified(location); + if (contributionCache != null) { + if (contributionCache.contributionLastModified == lastModified) { + Contribution contribution = contributionCache.contribution; + contribution.setUnresolved(false); + contributions.getContributions().add(contribution); + continue; + } + + // Reset contribution cache + cache.contributions.remove(location); + } + + try { + Contribution contribution = (Contribution)contributionProcessor.read(null, uri, location); + contribution.setUnresolved(false); + contributions.getContributions().add(contribution); + + // Cache contribution + contributionCache = new ContributionCache(); + contributionCache.contribution = contribution; + contributionCache.contributionLastModified = lastModified; + cache.contributions.put(location, contributionCache); + + + // Make sure that the cloud contribution does not contain + // default imports/exports as we want to isolate it from application + // provided contributions + if (contribution.getURI().equals(DEPLOYMENT_CONTRIBUTION_URI)) { + for (Iterator i = contribution.getImports().iterator(); i.hasNext(); ) { + Import import_ = i.next(); + if (import_ instanceof DefaultImport) { + i.remove(); + } + } + for (Iterator i = contribution.getExports().iterator(); i.hasNext(); ) { + Export export = i.next(); + if (export instanceof DefaultExport) { + i.remove(); + } + } + } + + } catch (ContributionReadException e) { + Contribution contribution = contributionFactory.createContribution(); + contribution.setURI(c.getURI()); + contribution.setLocation(c.getLocation()); + contribution.setUnresolved(true); + contributions.getContributions().add(contribution); + } + } + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + return contributions; + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionServiceImpl.java new file mode 100644 index 0000000000..a4d7680cb0 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionServiceImpl.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.IOException; +import java.net.URLDecoder; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a contribution collection service component. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={Servlet.class}) +public class ContributionServiceImpl extends HttpServlet implements Servlet { + private static final long serialVersionUID = -4759297945439322773L; + + private static final Logger logger = Logger.getLogger(ContributionServiceImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + + // The key is the contribution URI + String key = path.startsWith("/")? path.substring(1) : path; + logger.fine("get " + key); + + // Get the item describing the composite + Item item; + try { + item = contributionCollection.get(key); + } catch (NotFoundException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + // Redirect to the actual contribution location + response.sendRedirect("/files/" + item.getAlternate()); + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionsReader.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionsReader.java new file mode 100644 index 0000000000..ef5578c9da --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/ContributionsReader.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.domain.manager.impl; + +import org.apache.tuscany.sca.contribution.Contribution; + +public interface ContributionsReader { + + Contribution[] readContributions(); + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeCollectionImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeCollectionImpl.java new file mode 100644 index 0000000000..63af213fbb --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeCollectionImpl.java @@ -0,0 +1,481 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeAlternateLink; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeKey; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeSourceLink; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeTitle; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.contributionURI; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.lastModified; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.locationURL; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.apache.tuscany.sca.domain.manager.impl.DeployableCompositeCollectionImpl.Cache.ContributionCache; +import org.apache.tuscany.sca.implementation.node.NodeImplementation; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; +import org.apache.tuscany.sca.workspace.builder.ContributionDependencyBuilder; +import org.apache.tuscany.sca.workspace.builder.impl.ContributionDependencyBuilderImpl; +import org.apache.tuscany.sca.workspace.processor.impl.ContributionContentProcessor; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a deployable composite collection service. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces = { ItemCollection.class, LocalItemCollection.class, ContributionsReader.class }) +public class DeployableCompositeCollectionImpl implements ItemCollection, + LocalItemCollection, ContributionsReader { + + private static final Logger logger = Logger + .getLogger(DeployableCompositeCollectionImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + private ModelFactoryExtensionPoint modelFactories; + private ModelResolverExtensionPoint modelResolvers; + private URLArtifactProcessor contributionProcessor; + private XMLOutputFactory outputFactory; + private ContributionDependencyBuilder contributionDependencyBuilder; + private Monitor monitor; + + /** + * Cache contribution models. + */ + static class Cache { + static class ContributionCache { + private Contribution contribution; + private long contributionLastModified; + } + + private Map contributions = new HashMap(); + } + + private Cache cache = new Cache(); + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + + ExtensionPointRegistry extensionPoints = domainManagerConfiguration + .getExtensionPoints(); + + // Create a monitor + UtilityExtensionPoint utilities = extensionPoints + .getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities + .getUtility(MonitorFactory.class); + monitor = monitorFactory.createMonitor(); + + // Get model factories + modelFactories = extensionPoints + .getExtensionPoint(ModelFactoryExtensionPoint.class); + XMLInputFactory inputFactory = modelFactories + .getFactory(XMLInputFactory.class); + outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, + true); + + // Get and initialize artifact processors + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints + .getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + StAXArtifactProcessor staxProcessor = new ExtensibleStAXArtifactProcessor( + staxProcessors, inputFactory, outputFactory, monitor); + + URLArtifactProcessorExtensionPoint urlProcessors = extensionPoints + .getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + URLArtifactProcessor urlProcessor = new ExtensibleURLArtifactProcessor( + urlProcessors, monitor); + + // Create contribution processor + modelResolvers = extensionPoints + .getExtensionPoint(ModelResolverExtensionPoint.class); + contributionProcessor = new ContributionContentProcessor( + extensionPoints, monitor); + + // Create contribution and composite builders + contributionDependencyBuilder = new ContributionDependencyBuilderImpl( + monitor); + } + + public Entry[] getAll() { + logger.fine("getAll"); + + // Return all the deployable composites in the contributions + List> entries = new ArrayList>(); + + // Get the list of contributions in the workspace + Entry[] contributionEntries = contributionCollection + .getAll(); + + // Read contribution metadata + for (Entry contributionEntry : contributionEntries) { + Item contributionItem = contributionEntry.getData(); + Contribution contribution; + try { + contribution = contribution(contributionEntry.getKey(), + contributionItem.getAlternate()); + } catch (ContributionReadException e) { + continue; + } + + // Create entries for the deployable composites + for (Composite deployable : contribution.getDeployables()) { + entries.add(entry(contribution, deployable)); + } + + } + return entries.toArray(new Entry[entries.size()]); + } + + public Contribution[] readContributions() { + + // Get the list of contributions in the workspace + Entry[] contributionEntries = contributionCollection + .getAll(); + + LinkedList contributions = new LinkedList(); + + // Read contribution metadata + for (Entry contributionEntry : contributionEntries) { + Item contributionItem = contributionEntry.getData(); + Contribution contribution; + try { + contribution = contribution(contributionEntry.getKey(), + contributionItem.getAlternate()); + + } catch (ContributionReadException e) { + continue; + } + + LinkedList resolvedComposites = new LinkedList(); + + for (Composite composite : contribution.getDeployables()) { + + // find the deployable composite + composite = contribution.getModelResolver().resolveModel( + Composite.class, composite); + + resolvedComposites.add(composite); + + } + + contribution.getDeployables().clear(); + contribution.getDeployables().addAll(resolvedComposites); + + contributions.add(contribution); + + } + + return contributions.toArray(new Contribution[0]); + + } + + public Item get(String key) throws NotFoundException { + logger.fine("get " + key); + + // Get the specified contribution info + String contributionURI = contributionURI(key); + Item contributionItem = contributionCollection.get(contributionURI); + + // Read the contribution + Contribution contribution; + try { + contribution = contribution(contributionURI, contributionItem + .getAlternate()); + } catch (ContributionReadException e) { + throw new NotFoundException(key); + } + + // Find the specified deployable composite + QName qname = compositeQName(key); + for (Composite deployable : contribution.getDeployables()) { + if (qname.equals(deployable.getName())) { + // find the deployable composite + deployable = contribution.getModelResolver().resolveModel( + Composite.class, deployable); + + if (deployable.isUnresolved()) { + throw new NotFoundException(key); + } + + // Return an item describing the deployable composite + return item(contribution, deployable); + } + } + + throw new NotFoundException(key); + } + + public String post(String key, Item item) { + throw new UnsupportedOperationException(); + } + + public void put(String key, Item item) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public void delete(String key) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public Entry[] query(String queryString) { + logger.fine("query " + queryString); + + if (queryString.startsWith("contribution=")) { + + // Return all the deployable composites in the specified + // contribution + List> entries = new ArrayList>(); + + // Get the specified contribution info + String contributionURI = queryString.substring(queryString + .indexOf('=') + 1); + Item contributionItem; + try { + contributionItem = contributionCollection.get(contributionURI); + } catch (NotFoundException e) { + return entries.toArray(new Entry[entries.size()]); + } + + // Read the contribution + Contribution contribution; + try { + contribution = contribution(contributionURI, contributionItem + .getAlternate()); + } catch (ContributionReadException e) { + return entries.toArray(new Entry[entries.size()]); + } + + // Create entries for the deployable composites + for (Composite deployable : contribution.getDeployables()) { + entries.add(entry(contribution, deployable)); + } + + return entries.toArray(new Entry[entries.size()]); + + } else { + throw new UnsupportedOperationException(); + } + } + + /** + * Returns the contribution with the given URI. + * + * @param contributionURI + * @param contributionLocation + * @return + * @throws NotFoundException + */ + private Contribution contribution(String contributionURI, + String contributionLocation) throws ContributionReadException { + try { + URI uri = URI.create(contributionURI); + URL location = locationURL(contributionLocation); + + // Get contribution from cache + ContributionCache contributionCache = cache.contributions + .get(location); + long lastModified = lastModified(location); + if (contributionCache != null) { + if (contributionCache.contributionLastModified == lastModified) { + return contributionCache.contribution; + } + + // Reset contribution cache + cache.contributions.remove(location); + } + + Contribution contribution = (Contribution) contributionProcessor + .read(null, uri, location); + + // TODO - analyse dependencies here? + + // contributionProcessor.resolve(contribution, new + // DefaultModelResolver()); + + // Cache contribution + contributionCache = new ContributionCache(); + contributionCache.contribution = contribution; + contributionCache.contributionLastModified = lastModified; + cache.contributions.put(location, contributionCache); + + return contribution; + + } catch (ContributionReadException e) { + throw e; + } catch (MalformedURLException e) { + throw new ContributionReadException(e); + // } catch (ContributionResolveException e) { + // throw new ContributionReadException(e); + } catch (Throwable e) { + throw new ContributionReadException(e); + } + } + + /** + * Returns the entry contents describing a composite. + * + * @param composite + * @return + */ + private static String content(Composite composite) { + StringBuffer sb = new StringBuffer(); + List components = composite.getComponents(); + for (int i = 0, n = components.size(); i < n; i++) { + Component component = components.get(i); + if (component.getImplementation() instanceof NodeImplementation) { + List services = component.getServices(); + if (!services.isEmpty()) { + List bindings = services.get(0).getBindings(); + if (!bindings.isEmpty()) { + + // List node URIs + sb.append("Node URI: "); + sb.append(component.getServices().get(0).getBindings() + .get(0).getURI()); + break; + } + } + } else { + + // List component names + if (sb.length() == 0) { + sb.append("Components: "); + } else { + sb.append(" "); + } + sb.append(component.getName()); + } + } + if (sb.length() != 0) { + sb.append(""); + } + return sb.toString(); + } + + /** + * Returns the link to the resource related to a composite. + * + * @param composite + * @return + */ + private static String relatedLink(Composite composite) { + for (Component component : composite.getComponents()) { + if (component.getImplementation() instanceof NodeImplementation) { + NodeImplementation nodeImplementation = (NodeImplementation) component + .getImplementation(); + Composite deployable = nodeImplementation.getComposite(); + String contributionURI = deployable.getURI(); + QName qname = deployable.getName(); + String key = compositeKey(contributionURI, qname); + return "/composite-source/" + key; + } + } + return null; + } + + /** + * Returns an entry describing the given deployable. + * + * @param contribution + * @param deployable + * @return + */ + private static Entry entry(Contribution contribution, + Composite deployable) { + Entry entry = new Entry(); + entry.setKey(DomainManagerUtil.compositeKey(contribution.getURI(), + deployable.getName())); + entry.setData(item(contribution, deployable)); + return entry; + } + + /** + * Returns an item describing the given deployable. + * + * @param contribution + * @param deployable + * @return + */ + private static Item item(Contribution contribution, Composite deployable) { + String contributionURI = contribution.getURI(); + String contributionLocation = contribution.getLocation(); + QName qname = deployable.getName(); + String deployableURI = deployable.getURI(); + Item item = new Item(); + item.setTitle(compositeTitle(contributionURI, qname)); + item.setContents(content(deployable)); + item.setLink(compositeSourceLink(contributionURI, qname)); + item.setAlternate(compositeAlternateLink(contributionLocation, + deployableURI)); + item.setRelated(relatedLink(deployable)); + return item; + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeServiceImpl.java new file mode 100644 index 0000000000..14ab9579f4 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployableCompositeServiceImpl.java @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a service that returns the source of a deployable composite. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(Servlet.class) +public class DeployableCompositeServiceImpl extends HttpServlet implements Servlet { + private static final long serialVersionUID = -3477992129462720902L; + + private static final Logger logger = Logger.getLogger(DeployableCompositeServiceImpl.class.getName()); + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + @Reference + public LocalItemCollection deployableCollection; + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + + ExtensionPointRegistry extensionPoints = domainManagerConfiguration.getExtensionPoints(); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // Expect a key in the form + // composite:contributionURI;namespace;localName + // and return the corresponding source file + + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + String key = path.startsWith("/")? path.substring(1) : path; + logger.fine("get " + key); + + // Get the item describing the composite + Item item; + try { + item = deployableCollection.get(key); + } catch (NotFoundException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + // Redirect if there is no composite file + String uri = item.getAlternate(); + if (uri == null) { + response.sendRedirect("/composite-generated/" + key); + return; + } + + // Read the composite file and write to response + InputStream is; + try { + URLConnection connection = new URL(uri).openConnection(); + connection.setUseCaches(false); + connection.connect(); + is = connection.getInputStream(); + } catch (FileNotFoundException ex) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } + + response.setContentType("text/xml"); + ServletOutputStream os = response.getOutputStream(); + byte[] buffer = new byte[4096]; + for (;;) { + int n = is.read(buffer); + if (n < 0) { + break; + } + os.write(buffer, 0, n); + } + is.close(); + os.flush(); + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployedCompositeCollectionImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployedCompositeCollectionImpl.java new file mode 100644 index 0000000000..6501f2c4b9 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DeployedCompositeCollectionImpl.java @@ -0,0 +1,417 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.DEPLOYMENT_CONTRIBUTION_URI; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeKey; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeSourceLink; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeTitle; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.contributionURI; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.apache.tuscany.sca.domain.search.DomainSearch; +import org.apache.tuscany.sca.domain.search.IndexException; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.osoa.sca.ServiceRuntimeException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; +import org.w3c.dom.Document; + +/** + * Implementation of a composite collection service. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={ItemCollection.class,LocalItemCollection.class}) +public class DeployedCompositeCollectionImpl implements ItemCollection, LocalItemCollection { + private static final Logger logger = Logger.getLogger(DeployedCompositeCollectionImpl.class.getName()); + + @Property + public String compositeFile; + + @Property + public String deploymentContributionDirectory; + + @Reference + public LocalItemCollection deployableCollection; + + @Reference + public DomainSearch domainSearch; + + @Reference(required=false) + public LocalItemCollection processCollection; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + @Reference + public ContributionsReader contributionReader; + + private ModelFactoryExtensionPoint modelFactories; + private AssemblyFactory assemblyFactory; + private StAXArtifactProcessor compositeProcessor; + private XMLOutputFactory outputFactory; + private DocumentBuilder documentBuilder; + + /** + * Cache domain composite model. + */ + static class Cache { + private Composite compositeCollection; + private long compositeCollectionLastModified; + } + + private Cache cache = new Cache(); + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + + // Create factories + ExtensionPointRegistry extensionPoints = domainManagerConfiguration.getExtensionPoints(); + modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true); + + // Create composite processor + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + compositeProcessor = staxProcessors.getProcessor(Composite.class); + + // Create a document builder (used to pretty print XML) + documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + public Entry[] getAll() { + logger.fine("getAll"); + + // Return all the composites in the domain composite + List> entries = new ArrayList>(); + Composite compositeCollection = readCompositeCollection(); + for (Composite composite: compositeCollection.getIncludes()) { + String contributionURI = composite.getURI(); + QName qname = composite.getName(); + String key = compositeKey(contributionURI, qname); + Item item; + try { + item = deployableCollection.get(key); + } catch (NotFoundException e) { + item = new Item(); + item.setTitle(compositeTitle(contributionURI, qname)); + item.setLink(compositeSourceLink(contributionURI, qname)); + item.setContents("Problem: Composite not found"); + } + Entry entry = new Entry(); + entry.setKey(key); + entry.setData(item); + entries.add(entry); + } + return entries.toArray(new Entry[entries.size()]); + } + + public Item get(String key) throws NotFoundException { + logger.fine("get " + key); + + String contributionURI = contributionURI(key); + QName qname = compositeQName(key); + + // Look for the specified composite in the domain composite + List> entries = new ArrayList>(); + Composite compositeCollection = readCompositeCollection(); + for (Composite composite: compositeCollection.getIncludes()) { + if (contributionURI.equals(composite.getURI()) && qname.equals(composite.getName())) { + return deployableCollection.get(key); + } + } + throw new NotFoundException(key); + } + + public String post(String key, Item item) { + logger.fine("post " + key); + + String contributionURI = contributionURI(key); + QName qname = compositeQName(key); + + // Adds a new composite to the domain composite + Composite compositeCollection = readCompositeCollection(); + Composite composite = assemblyFactory.createComposite(); + composite.setName(qname); + composite.setURI(contributionURI); + composite.setUnresolved(true); + compositeCollection.getIncludes().add(composite); + + // Optionally, write the composite contents in a new composite file + // under the deployment composites directory, if that directory is + // configured on this component + if (deploymentContributionDirectory != null && item.getContents() != null) { + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + File directory = new File(rootDirectory + "/" + deploymentContributionDirectory); + if (!directory.exists()) { + directory.mkdirs(); + } + File file = new File(directory, qname.getLocalPart() + ".composite"); + try { + Writer w = new OutputStreamWriter(new FileOutputStream(file)); + w.write("\n"); + w.write(item.getContents()); + w.close(); + } catch (IOException e) { + throw new ServiceRuntimeException(e); + } + } + + // Write the composite collection + writeCompositeCollection(compositeCollection); + + updateDomainSearch(contributionURI); + + return key; + } + + public void put(String key, Item item) throws NotFoundException { + logger.fine("put " + key); + + String contributionURI = contributionURI(key); + QName qname = compositeQName(key); + + // Update a composite already in the domain composite + Composite compositeCollection = readCompositeCollection(); + Composite newComposite = assemblyFactory.createComposite(); + newComposite.setName(qname); + newComposite.setURI(contributionURI); + newComposite.setUnresolved(true); + List composites = compositeCollection.getIncludes(); + for (int i = 0, n = composites.size(); i < n; i++) { + Composite composite = composites.get(i); + if (contributionURI.equals(composite.getURI()) && qname.equals(composite.getName())) { + composites.set(i, newComposite); + + // Write the domain composite + writeCompositeCollection(compositeCollection); + + updateDomainSearch(contributionURI); + + return; + } + } + throw new NotFoundException(key); + } + + public void delete(String key) throws NotFoundException { + logger.fine("delete " + key); + + String contributionURI = contributionURI(key); + QName qname = compositeQName(key); + + // Delete/stop the corresponding process, if any + try { + processCollection.delete(qname.getLocalPart()); + } catch (Exception e) {} + + // Delete a composite from the composite collection + Composite compositeCollection = readCompositeCollection(); + List composites = compositeCollection.getIncludes(); + Composite deleted = null; + for (int i = 0, n = composites.size(); i < n; i++) { + Composite composite = composites.get(i); + if (contributionURI.equals(composite.getURI()) && qname.equals(composite.getName())) { + composites.remove(i); + deleted = composite; + + // Write the domain composite + writeCompositeCollection(compositeCollection); + updateDomainSearch(contributionURI); + + break; + + } + } + + // Delete the file too if it is in the deployment contribution directory + if (deploymentContributionDirectory != null && contributionURI.equals(DEPLOYMENT_CONTRIBUTION_URI)) { + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + File file = new File(rootDirectory + "/" + deploymentContributionDirectory, qname.getLocalPart() + ".composite"); + if (file.exists()) { + file.delete(); + } + } + + if (deleted == null) { + throw new NotFoundException(key); + } + } + + private void updateDomainSearch(String contributionURI) { + Contribution[] contributions = this.contributionReader.readContributions(); + + for (Contribution contribution : contributions) { + + if (contributionURI.equals(contribution.getURI())) { + + try { + this.domainSearch.updateContribution(contribution, contribution); + + } catch (IndexException e) { + logger.log(Level.WARNING, "Could not update contribution " + contribution.getURI() + " on the index, reason: " + e.getMessage()); + } + + break; + + } + + } + + } + + public Entry[] query(String queryString) { + throw new UnsupportedOperationException(); + } + + /** + * Reads the domain composite. + * + * @return the domain composite + * @throws ServiceRuntimeException + */ + private Composite readCompositeCollection() throws ServiceRuntimeException { + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + Composite compositeCollection; + File file = new File(rootDirectory + "/" + compositeFile); + if (file.exists()) { + + // Get composite collection from cache + if (cache.compositeCollection != null && file.lastModified() == cache.compositeCollectionLastModified) { + compositeCollection = cache.compositeCollection; + + } else { + + XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class); + try { + FileInputStream is = new FileInputStream(file); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + compositeCollection = compositeProcessor.read(reader); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + // Cache composite collection + cache.compositeCollectionLastModified = file.lastModified(); + cache.compositeCollection = compositeCollection; + } + + } else { + compositeCollection = assemblyFactory.createComposite(); + String name; + int d = compositeFile.lastIndexOf('.'); + if (d != -1) { + name = compositeFile.substring(0, d); + } else { + name = compositeFile; + } + compositeCollection.setName(new QName(Constants.SCA10_TUSCANY_NS, name)); + + // Cache composite collection + cache.compositeCollectionLastModified = 0; + cache.compositeCollection = compositeCollection; + } + return compositeCollection; + } + + /** + * Write the domain composite back to disk. + * + * @param compositeCollection + */ + private void writeCompositeCollection(Composite compositeCollection) { + try { + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + // First write to a byte stream + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(bos); + compositeProcessor.write(compositeCollection, writer); + + // Parse again to pretty format the document + Document document = documentBuilder.parse(new ByteArrayInputStream(bos.toByteArray())); + OutputFormat format = new OutputFormat(); + format.setIndenting(true); + format.setIndent(2); + + // Write to domain.composite + File file = new File(rootDirectory + "/" + compositeFile); + FileOutputStream os = new FileOutputStream(file); + XMLSerializer serializer = new XMLSerializer(os, format); + serializer.serialize(document); + + // Cache composite collection + cache.compositeCollection = compositeCollection; + cache.compositeCollectionLastModified = file.lastModified(); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfiguration.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfiguration.java new file mode 100644 index 0000000000..1831728f07 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfiguration.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import org.apache.tuscany.sca.core.ExtensionPointRegistry; + +/** + * Domain manager configuration service interface. + * + * @version $Rev$ $Date$ + */ +public interface DomainManagerConfiguration { + + /** + * Sets the domain manager root directory. + * + * @param rootDirectory + */ + void setRootDirectory(String rootDirectory); + + /** + * Returns the domain manager root directory. + * + * @return the domain manager root directory + */ + String getRootDirectory(); + + /** + * Returns the extension point registry used in the + * domain manager. + * + * @return + */ + ExtensionPointRegistry getExtensionPoints(); + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfigurationImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfigurationImpl.java new file mode 100644 index 0000000000..a5ce6e12d6 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerConfigurationImpl.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.ModuleActivator; +import org.apache.tuscany.sca.core.ModuleActivatorExtensionPoint; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a domain manager configuration component. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(DomainManagerConfiguration.class) +public class DomainManagerConfigurationImpl implements DomainManagerConfiguration { + + private String rootDirectory = "."; + private ExtensionPointRegistry extensionPoints; + + @Init + public void initialize() { + + // Create extension point registry + extensionPoints = new DefaultExtensionPointRegistry(); + + // Initialize module activators + ModuleActivatorExtensionPoint moduleActivators = extensionPoints.getExtensionPoint(ModuleActivatorExtensionPoint.class); + for (ModuleActivator activator: moduleActivators.getModuleActivators()) { + try { + activator.start(extensionPoints); + } catch (Exception e) { + //FIXME fix the module activators that have cross module dependencies + // and currently fail when the whole runtime is not present + } + } + } + + @Destroy + public void destroy() { + ModuleActivatorExtensionPoint moduleActivators = extensionPoints.getExtensionPoint(ModuleActivatorExtensionPoint.class); + for (ModuleActivator activator: moduleActivators.getModuleActivators()) { + try { + activator.stop(extensionPoints); + } catch (Exception e) { + //FIXME fix the module activators that have cross module dependencies + // and currently fail when the whole runtime is not present + } + } + } + + public String getRootDirectory() { + return rootDirectory; + } + + public void setRootDirectory(String rootDirectory) { + this.rootDirectory = rootDirectory; + } + + public ExtensionPointRegistry getExtensionPoints() { + return extensionPoints; + } +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerUtil.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerUtil.java new file mode 100644 index 0000000000..c015689cf1 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerUtil.java @@ -0,0 +1,295 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.core.assembly.CompositeActivator; +import org.apache.tuscany.sca.core.context.ServiceReferenceImpl; +import org.apache.tuscany.sca.core.invocation.ProxyFactory; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.osoa.sca.ServiceReference; +import org.osoa.sca.ServiceRuntimeException; + +/** + * Common functions and constants used by the admin components. + * + * @version $Rev$ $Date$ + */ +public final class DomainManagerUtil { + + static final String DEPLOYMENT_CONTRIBUTION_URI = "http://tuscany.apache.org/cloud"; + + /** + * Extracts a qname from a key expressed as contributionURI;namespace;localpart. + * @param key + * @return + */ + static QName compositeQName(String key) { + int i = key.indexOf(';'); + key = key.substring(i + 1); + i = key.indexOf(';'); + return new QName(key.substring(0, i), key.substring(i + 1)); + } + + /** + * Returns a composite title expressed as contributionURI - namespace;localpart. + * @param qname + * @return + */ + static String compositeTitle(String uri, QName qname) { + if (uri.equals(DEPLOYMENT_CONTRIBUTION_URI)) { + return qname.getLocalPart(); + } else { + return uri + " - " + qname.getNamespaceURI() + ";" + qname.getLocalPart(); + } + } + + /** + * Extracts a contribution uri from a key expressed as contributionURI;namespace;localpart. + * @param key + * @return + */ + static String contributionURI(String key) { + int i = key.indexOf(';'); + return key.substring("composite:".length(), i); + } + + /** + * Returns a composite key expressed as contributionURI;namespace;localpart. + * @param qname + * @return + */ + static String compositeKey(String uri, QName qname) { + return "composite:" + uri + ';' + qname.getNamespaceURI() + ';' + qname.getLocalPart(); + } + + /** + * Returns a link to the source of a composite + * @param contributionURI + * @param qname + * @return + */ + static String compositeSourceLink(String contributionURI, QName qname) { + return "/composite-source/" + compositeKey(contributionURI, qname); + } + + /** + * Returns a composite title expressed as contributionURI - namespace;localpart. + * @param qname + * @return + */ + static String compositeSimpleTitle(String uri, QName qname) { + if (uri.equals(DomainManagerUtil.DEPLOYMENT_CONTRIBUTION_URI)) { + return qname.getLocalPart(); + } else { + return qname.getNamespaceURI() + ";" + qname.getLocalPart(); + } + } + + /** + * Returns a URL from a location string. + * @param location + * @return + * @throws MalformedURLException + */ + static URL locationURL(String location) throws MalformedURLException { + String scheme = null; + URI uri = null; + + IllegalArgumentException uriException = null; + try { + uri = URI.create(location); + scheme = uri.getScheme(); + }catch (java.lang.IllegalArgumentException e) { + uriException = e; + } + + if (scheme == null) { + File file = new File(location); + return file.toURI().toURL(); + } else if (scheme.equals("file")) { + File file = new File(location.substring(5)); + return file.toURI().toURL(); + } else if(uri == null){ + throw uriException; + } else { + return uri.toURL(); + } + } + + /** + * Returns a link to a deployable composite. + * + * If the containing contribution is a local directory, return the URI of the local composite file + * inside the contribution. + * + * If the containing contribution is a local or remote file, return a URI of the form: + * jar: contribution URI !/ composite URI. + * + * @param contributionLocation + * @param deployableURI + * @return + */ + static String compositeAlternateLink(String contributionLocation, String deployableURI) { + if (deployableURI == null) { + return null; + } + URI u = URI.create(contributionLocation); + String uri; + if ("file".equals(u.getScheme())) { + String path = u.toString().substring(5); + File file = new File(path); + if (file.isDirectory()) { + if (contributionLocation.endsWith("/")) { + uri = contributionLocation + deployableURI; + } else { + uri = contributionLocation + "/" + deployableURI; + } + } else { + uri = contributionLocation + "!/" + deployableURI; + } + } else { + uri = contributionLocation + "!/" + deployableURI; + } + int e = uri.indexOf("!/"); + if (e != -1) { + int s = uri.lastIndexOf('/', e - 2) +1; + if (uri.substring(s, e).contains(".")) { + uri = "jar:" + uri; + } else { + uri = uri.substring(0, e) + uri.substring(e + 1); + } + } + return uri; + } + + /** + * Extract a node URI from an ATOM entry content. + * + * @param content + * @return + */ + static String nodeURI(String content) { + if (content != null) { + int bs = content.indexOf(""); + if (bs != -1) { + content = content.substring(bs + 19); + int es = content.indexOf(""); + if (es != -1) { + return content.substring(0, es); + } + } + } + return null; + } + + /** + * Create a new service reference dynamically. + * + * @param + * @param businessInterface + * @param binding + * @param assemblyFactory + * @param compositeActivator + * @return + */ + static ServiceReference dynamicReference(Class businessInterface, Binding binding, AssemblyFactory assemblyFactory, CompositeActivator compositeActivator) { + try { + + Composite composite = assemblyFactory.createComposite(); + composite.setName(new QName("http://tuscany.apache.org/xmlns/sca/1.0", "default")); + RuntimeComponent component = (RuntimeComponent)assemblyFactory.createComponent(); + component.setName("default"); + component.setURI("default"); + compositeActivator.configureComponentContext(component); + composite.getComponents().add(component); + RuntimeComponentReference reference = (RuntimeComponentReference)assemblyFactory.createComponentReference(); + reference.setName("default"); + JavaInterfaceFactory javaInterfaceFactory = compositeActivator.getJavaInterfaceFactory(); + InterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract(); + interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(businessInterface)); + reference.setInterfaceContract(interfaceContract); + component.getReferences().add(reference); + reference.setComponent(component); + reference.getBindings().add(binding); + + ProxyFactory proxyFactory = compositeActivator.getProxyFactory(); + return new ServiceReferenceImpl(businessInterface, component, reference, binding, proxyFactory, compositeActivator); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + /** + * Returns the last modified time of the content at the given URL. + * + * @param url + * @return + * @throws IOException + */ + static long lastModified(URL url) throws IOException { + + if (url.getProtocol() == null || "file".equals(url.getProtocol())) { + return lastModified(new File(url.getPath())); + } else { + URLConnection connection = url.openConnection(); + long lastModified = connection.getLastModified(); + return lastModified; + } + } + + /** + * Returns the last modified time of the given file or directory. + * + * @param file + * @return + */ + static long lastModified(File file) { + if (file.isDirectory()) { + long lastModified = file.lastModified(); + + for (File child: file.listFiles()) { + long m = lastModified(child); + if (m > lastModified) { + lastModified = m; + } + } + return lastModified; + + } else { + return file.lastModified(); + } + } +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileCollectionImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileCollectionImpl.java new file mode 100644 index 0000000000..a53250515a --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileCollectionImpl.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a file collection service component. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(ItemCollection.class) +public class FileCollectionImpl implements ItemCollection { + + private static final Logger logger = Logger.getLogger(FileCollectionImpl.class.getName()); + + @Property + public String directoryName; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + /** + * Initialize the component. + */ + @Init + public void initialize() throws IOException { + } + + public Entry[] getAll() { + logger.fine("getAll"); + + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + + // Return all the files + List> entries = new ArrayList>(); + File directory = new File(rootDirectory + "/" + directoryName); + if (directory.exists()) { + for (File file: directory.listFiles()) { + if (file.getName().startsWith(".")) { + continue; + } + entries.add(entry(file.getName())); + } + } + return entries.toArray(new Entry[entries.size()]); + } + + public Item get(String key) throws NotFoundException { + logger.fine("get " + key); + return item(key); + } + + public String post(String key, Item item) { + throw new UnsupportedOperationException(); + } + + public void put(String key, Item item) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public void delete(String key) throws NotFoundException { + logger.fine("delete " + key); + + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + File directory = new File(rootDirectory + "/" + directoryName); + File file = new File(directory, key); + if (file.exists()) { + file.delete(); + } else { + throw new NotFoundException(key); + } + } + + public Entry[] query(String queryString) { + throw new UnsupportedOperationException(); + } + + /** + * Returns an entry representing a file. + * + * @param fileName + * @return + */ + private static Entry entry(String fileName) { + Entry entry = new Entry(); + entry.setKey(fileName); + entry.setData(item(fileName)); + return entry; + } + + /** + * Returns an item representing a file. + * + * @param fileName + * @return + */ + private static Item item(String fileName) { + Item item = new Item(); + item.setTitle(fileName); + item.setLink("/files/" + fileName); + return item; + } +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileServiceImpl.java new file mode 100644 index 0000000000..1493b73248 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/FileServiceImpl.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.util.List; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a servlet component supporting file upload/download. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(Servlet.class) +public class FileServiceImpl extends HttpServlet { + private static final long serialVersionUID = -4560385595481971616L; + + private static final Logger logger = Logger.getLogger(FileServiceImpl.class + .getName()); + + @Property + public String directoryName; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + @Reference + public LocalItemCollection contributionCollection; + + private ServletFileUpload upload; + + /** + * Initialize the component. + */ + @Init + public void initialize() throws IOException { + upload = new ServletFileUpload(new DiskFileItemFactory()); + } + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + + // Upload files + String rootDirectory = domainManagerConfiguration.getRootDirectory(); + try { + for (FileItem item : (List) upload.parseRequest(request)) { + if (!item.isFormField()) { + File directory = new File(rootDirectory + "/" + + directoryName); + if (!directory.exists()) { + directory.mkdirs(); + } + logger.fine("post " + item.getName()); + item.write(new File(directory, item.getName())); + } + } + + // Redirect to the admin page + response.sendRedirect("/ui/files"); + } catch (Exception e) { + throw new IOException(e.toString()); + } + } + + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + // Download a file + String requestURI = URLDecoder.decode(request.getRequestURI(), "UTF-8"); + String path = requestURI.substring(request.getServletPath().length()); + if (path.startsWith("/")) { + path = path.substring(1); + } + logger.fine("get " + path); + + try { + + // Analyze the given path + String artifactURI; + if (path.startsWith("contribution=")) { + int semicolonIndex = path.indexOf(';'); + String contributionName = path.substring("contribution=" + .length(), semicolonIndex); + artifactURI = path.substring(semicolonIndex + 1); + + try { + Item item = this.contributionCollection + .get(contributionName); + + if (item == null) { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + + return; + + } + + path = item.getAlternate(); + + } catch (NotFoundException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + + return; + + } + + if (path.endsWith(".jar") || path.endsWith(".zip")) { + path = "jar:" + (path.startsWith("file:") ? "" : "file:") + path + '!' + (artifactURI.startsWith("/") ? "" : "/") + artifactURI; + + } else { + path += (path.endsWith("/") ? "" : "/") + artifactURI; + } + + } else { + artifactURI = null; + } + + URI uri = URI.create(path); + String scheme = uri.getScheme(); + if (scheme == null) { + + if (artifactURI != null) { + uri = URI.create("file:" + uri.toString()); + + } else { + + // If no scheme is specified then the path identifies file + // inside our directory + String rootDirectory = domainManagerConfiguration + .getRootDirectory(); + uri = new File(rootDirectory + "/" + directoryName, path) + .toURI(); + + } + + } else if (!scheme.equals("file") && !scheme.equals("jar")) { + + // If the scheme does not identify a local file, just redirect + // to the server + // hosting the file + response.sendRedirect(path); + } + + // Read the file and write to response + URLConnection connection = uri.toURL().openConnection(); + connection.setUseCaches(false); + connection.connect(); + InputStream is = connection.getInputStream(); + ServletOutputStream os = response.getOutputStream(); + byte[] buffer = new byte[4096]; + for (;;) { + int n = is.read(buffer); + if (n < 0) { + break; + } + os.write(buffer, 0, n); + } + is.close(); + os.flush(); + + } catch (FileNotFoundException e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND); + } + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeConfigurationServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeConfigurationServiceImpl.java new file mode 100644 index 0000000000..06d28b0502 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeConfigurationServiceImpl.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; + +import java.io.IOException; +import java.net.URLDecoder; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a service that returns a node configuration. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(Servlet.class) +public class NodeConfigurationServiceImpl extends HttpServlet implements Servlet { + private static final long serialVersionUID = 6913769467386954463L; + + private static final Logger logger = Logger.getLogger(NodeConfigurationServiceImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public LocalItemCollection cloudCollection; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + String key = path.startsWith("/")? path.substring(1) : path; + logger.fine("get " + key); + + // The key contains a node name, redirect + // to the corresponding composite config + + // Get the collection of cloud composites + Entry[] cloudEntries = cloudCollection.getAll(); + + // Find the specified node + for (Entry cloudEntry: cloudEntries) { + QName qname = compositeQName(cloudEntry.getKey()); + if (qname.getLocalPart().equals(key)) { + + // Found the specified node + String related = cloudEntry.getData().getRelated(); + int i = related.indexOf("composite:"); + if (i != -1) { + + // Redirect to its composite config + String compositeConfiguration = "/composite-config/?composite=" + related.substring(i); + response.sendRedirect(compositeConfiguration); + return; + } + } + } + + // Node not found + response.sendError(HttpServletResponse.SC_NOT_FOUND, key); + return; + } +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeProcessCollectionFacadeImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeProcessCollectionFacadeImpl.java new file mode 100644 index 0000000000..d68cfa3786 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/NodeProcessCollectionFacadeImpl.java @@ -0,0 +1,251 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.nodeURI; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.binding.atom.AtomBindingFactory; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.assembly.CompositeActivator; +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.ServiceRuntimeException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a node process collection service. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={ItemCollection.class, LocalItemCollection.class}) +public class NodeProcessCollectionFacadeImpl implements ItemCollection, LocalItemCollection { + + private static final Logger logger = Logger.getLogger(NodeProcessCollectionFacadeImpl.class.getName()); + + @Reference + public LocalItemCollection cloudCollection; + + @Reference + public ItemCollection processCollection; + + @Reference + public DomainManagerConfiguration domainManagerConfiguration; + + private AssemblyFactory assemblyFactory; + private AtomBindingFactory atomBindingFactory; + private CompositeActivator compositeActivator; + + /** + * Initialize the component. + */ + @Init + public void initialize() { + + // Get its composite activator + //FIXME + //compositeActivator = runtime.getCompositeActivator(); + + // Get the model factories + ExtensionPointRegistry extensionPoints = domainManagerConfiguration.getExtensionPoints(); + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + atomBindingFactory = modelFactories.getFactory(AtomBindingFactory.class); + } + + public Entry[] getAll() { + logger.fine("getAll"); + + // Get the collection of nodes + Entry[] nodeEntries = cloudCollection.getAll(); + + // Dispatch to the hosts hosting these nodes + List> entries = new ArrayList>(); + for (String host: hosts(nodeEntries)) { + ItemCollection processCollection = processCollection(host); + for (Entry remoteEntry: processCollection.getAll()) { + entries.add(remoteEntry); + } + break; + } + + return entries.toArray(new Entry[entries.size()]); + } + + public Item get(String key) throws NotFoundException { + logger.fine("get " + key); + + // Get the host hosting the given node + String host = host(key); + + // Dispatch the request to that host + ItemCollection processCollection = processCollection(host); + return processCollection.get(key); + } + + public String post(String key, Item item) { + logger.fine("post " + key); + + // Get the host hosting the given node + String host; + try { + host = host(key); + } catch (NotFoundException e) { + throw new ServiceRuntimeException(e); + } + + // Dispatch the request to that host + ItemCollection processCollection = processCollection(host); + return processCollection.post(key, item); + } + + public void put(String key, Item item) throws NotFoundException { + throw new UnsupportedOperationException(); + } + + public void delete(String key) throws NotFoundException { + logger.fine("delete " + key); + + // Get the host hosting the given node + String host = host(key); + + // Dispatch the request to that host + ItemCollection processCollection = processCollection(host); + processCollection.delete(key); + } + + public Entry[] query(String queryString) { + logger.fine("query " + queryString); + + if (queryString.startsWith("node=")) { + String key = queryString.substring(queryString.indexOf('=') + 1); + + // Get the host hosting the given node + String host; + try { + host = host(key); + } catch (NotFoundException e) { + return new Entry[0]; + } + + // Dispatch the request to that host + ItemCollection processCollection = processCollection(host); + return processCollection.query(queryString); + + } else { + throw new UnsupportedOperationException(); + } + } + + private String host(String nodeName) throws NotFoundException { + + // Get the entry representing the given node + Entry nodeEntry = nodeEntry(cloudCollection.getAll(), nodeName); + if (nodeEntry == null) { + throw new NotFoundException(nodeName); + } + + // Get the host hosting it + return host(nodeEntry.getData()); + } + + /** + * Returns the entry representing the given node. + * + * @param entries + * @param name + * @return + */ + private static Entry nodeEntry(Entry[] entries, String name) { + for (Entry entry: entries) { + QName qname = compositeQName(entry.getKey()); + if (qname.getLocalPart().equals(name)) { + return entry; + } + } + return null; + } + + /** + * Returns the lists of hosts hosting the nodes in the given entries. + * + * @param entries + * @return + */ + private static List hosts(Entry[] entries) { + List hosts = new ArrayList(); + for (Entry entry: entries) { + String host = host(entry.getData()); + if (!hosts.contains(host)) { + hosts.add(host); + } + } + return hosts; + } + + /** + * Returns the host of the node represented by the given item. + * + * @param item + * @return + */ + private static String host(Item item) { + String uri = nodeURI(item.getContents()); + if (uri != null) { + return URI.create(uri).getHost(); + } else { + return null; + } + } + + /** + * Returns a proxy to the process collection service on the specified + * host. + * + * @param host + * @return + */ + private ItemCollection processCollection(String host) { + return processCollection; + +//FIXME +// AtomBinding binding = atomBindingFactory.createAtomBinding(); +// binding.setURI("http://" + host + ":9990/node/processes"); +// ServiceReference reference = dynamicReference(ItemCollection.class, binding, assemblyFactory, compositeActivator); +// return reference.getService(); + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/QuickStartServiceImpl.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/QuickStartServiceImpl.java new file mode 100644 index 0000000000..9c2092656e --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/QuickStartServiceImpl.java @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeKey; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.compositeQName; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.contributionURI; +import static org.apache.tuscany.sca.domain.manager.impl.DomainManagerUtil.nodeURI; + +import java.io.IOException; +import java.net.URI; +import java.net.URLDecoder; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.Servlet; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +/** + * Implementation of a component that provides a quick start path for a + * composite in a contribution. + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@Service(interfaces={Servlet.class}) +public class QuickStartServiceImpl extends HttpServlet { + private static final long serialVersionUID = -3477992129462720901L; + + private static final Logger logger = Logger.getLogger(QuickStartServiceImpl.class.getName()); + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public LocalItemCollection deployableCollection; + + @Reference + public LocalItemCollection domainCompositeCollection; + + @Reference + public LocalItemCollection cloudCollection; + + @Reference + public LocalItemCollection processCollection; + + /** + * Initialize the component. + */ + @Init + public void initialize() throws ParserConfigurationException { + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + if (path.startsWith("/")) { + path = path.substring(1); + } + + // Get the request parameters + String contributionURI = request.getParameter("contribution"); + String contributionLocation = request.getParameter("location"); + String compositeURI = request.getParameter("composite"); + String start = request.getParameter("start"); + + logger.info("Composite Quick Start."); + logger.info("Contribution URI: " + contributionURI); + logger.info("Contribution location: " + contributionLocation); + logger.info("Composite URI: " + compositeURI); + + // Look for the contribution in the workspace + Entry[] contributionEntries = contributionCollection.getAll(); + Entry contributionEntry = null; + for (Entry entry: contributionEntries) { + if (entry.getKey() != null && + contributionURI.equals(entry.getKey())) { + contributionEntry = entry; + break; + } + } + + // Add the contribution if necessary + if (contributionEntry == null) { + Item item = new Item(); + item.setLink(contributionLocation); + contributionCollection.post(contributionURI, item); + } + + // Look for the specified deployable composite in the contribution + String compositeKey = null; + Entry[] deployableEntries = deployableCollection.query("contribution=" + contributionURI); + for (Entry entry: deployableEntries) { + Item item = entry.getData(); + String compositeFileName = compositeURI.substring(compositeURI.lastIndexOf("/") + 1); + if (contributionURI.equals(contributionURI(entry.getKey())) && + (item.getAlternate().endsWith(compositeURI) || + item.getAlternate().endsWith(compositeFileName))) { + compositeKey = entry.getKey(); + break; + } + } + + if (compositeKey == null) { + logger.info("Composite not found"); + response.sendError(HttpServletResponse.SC_NOT_FOUND, compositeURI); + return; + } + + // Look for the deployable composite in the domain composite + try { + domainCompositeCollection.get(compositeKey); + } catch (NotFoundException e) { + + // Add the deployable composite to the domain composite + Item item = new Item(); + domainCompositeCollection.post(compositeKey, item); + } + + // Check if the deployable composite is already assigned a node + Entry[] nodeEntries = cloudCollection.getAll(); + String nodeName = null; + for (Entry entry: nodeEntries) { + Item item = entry.getData(); + String related = item.getRelated(); + if (related != null) { + int c = related.indexOf("composite:"); + related = related.substring(c); + if (compositeKey.equals(related)) { + nodeName = compositeQName(entry.getKey()).getLocalPart(); + } + } + } + + // Create a new node for the composite if necessary + if (nodeName == null) { + + // Construct node name and key + QName compositeName = compositeQName(compositeKey); + nodeName = compositeName.getLocalPart() + "Node"; + String nodeKey = compositeKey("http://tuscany.apache.org/cloud", new QName("http://tuscany.apache.org/cloud", nodeName)); + + // Find a free node port + Set nodePorts = new HashSet(); + for (Entry entry: nodeEntries) { + Item item = entry.getData(); + String uri = nodeURI(item.getContents()); + if (uri != null) { + URI u = URI.create(uri); + int port = u.getPort(); + if (port != -1) { + nodePorts.add(port); + } + } + } + String nodeURI = null; + for (int port = 8100; port<8200; port++) { + if (!nodePorts.contains(port)) { + nodeURI = "http://localhost:" + port; + break; + } + } + if (nodeURI == null) { + throw new RuntimeException("Couldn't find a free port for new node: " + nodeName); + } + + // Build the entry describing the node + Item item = new Item(); + String content = + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + item.setContents(content); + + // Create the new node + cloudCollection.post(nodeKey, item); + } + + // Finally, start the node + if ("true".equals(start)) { + processCollection.post(nodeName, new Item()); + } + + response.getWriter().print("Node " + nodeName + " OK."); + + } catch (Exception e) { + logger.log(Level.SEVERE, "Could not start composite", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); + } + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/Searcher.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/Searcher.java new file mode 100644 index 0000000000..edf9e4d062 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/impl/Searcher.java @@ -0,0 +1,479 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URL; +import java.util.Arrays; +import java.util.Map; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.ItemCollection; +import org.apache.tuscany.sca.data.collection.LocalItemCollection; +import org.apache.tuscany.sca.data.collection.NotFoundException; +import org.apache.tuscany.sca.domain.search.DomainSearch; +import org.apache.tuscany.sca.domain.search.IndexException; +import org.apache.tuscany.sca.domain.search.Result; +import org.apache.tuscany.sca.domain.search.impl.DomainSearchFormatter; +import org.apache.tuscany.sca.domain.search.impl.HighlightingUtil; +import org.apache.tuscany.sca.domain.search.impl.SearchFields; +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Scope; +import org.osoa.sca.annotations.Service; + +@Scope("COMPOSITE") +@Service(interfaces = {ItemCollection.class, LocalItemCollection.class}) +public class Searcher implements ItemCollection, LocalItemCollection { + static char[] characters = {'\u0001'/*  */, '\u0003'/*  */, '\u0004'/*  */,}; + + final private static String HTML_NEW_LINE = "
"; + + final private static String PATH_SEPARATOR = "/"; + + final private static int MAX_CONTENT_LINE_WIDTH = 300; + + final private static String HIGHLIGHT_START = ""; + + final private static String HIGHLIGHT_END = ""; + + @Reference + public ContributionsReader contributionReader; + + @Reference + public LocalItemCollection contributionCollection; + + @Reference + public DomainSearch domainSearch; + + private int elementCounter; + + public void delete(String key) throws NotFoundException { + + } + + private static void startIndentation(int size, StringWriter writer) { + writer.write("

"); + + } + + private static void endIndentation(StringWriter writer) { + writer.write("

"); + } + + public Item get(String key) throws NotFoundException { + + try { + + if (key.startsWith("highlight")) { + int lastSemicolonIndex = key.lastIndexOf(";"); + String artifact = key.substring(lastSemicolonIndex + 1); + int secondLastSemicolonIndex = key.lastIndexOf(";", lastSemicolonIndex - 1); + String contribution = key.substring(secondLastSemicolonIndex + 1, lastSemicolonIndex); + String query = key.substring("highlight".length(), secondLastSemicolonIndex); + + return highlightArtifact(contribution, artifact, query); + + } else if (key.startsWith("query")) { + return executeQuery(key.substring("query".length())); + + } else { + throw new NotFoundException("Invalid operation!"); + } + + } catch (Exception t) { + if (t instanceof NotFoundException) { + throw (NotFoundException)t; + } + throw new NotFoundException("Internal error!"); + } + + } + + private Item highlightArtifact(String contribution, String artifact, String query) throws NotFoundException { + + Item item = this.contributionCollection.get(contribution); + + if (item == null) { + throw new NotFoundException("contribution not found: " + contribution); + } + + String location = item.getAlternate(); + + if (location.endsWith(".jar") || location.endsWith(".zip")) { + location = + "jar:" + (location.startsWith("file:") ? "" : "file:") + + location + + '!' + + (artifact.startsWith("/") ? "" : "/") + + artifact; + + } else { + location += (location.endsWith("/") ? "" : "/") + artifact; + } + + try { + Reader reader = new InputStreamReader(new URL(location).openStream()); + StringBuilder sb = new StringBuilder(); + int c; + + // TODO: load the chars into an array buffer instead of one + // at a + // time + while ((c = reader.read()) != -1) { + char character = (char)c; + + if (!Character.isIdentifierIgnorable(character)) { + sb.append(character); + } + + } + + String highlightedText = this.domainSearch.highlight(SearchFields.FILE_CONTENT_FIELD, sb.toString(), query); + highlightedText = highlightedText.replaceAll("\n", "
"); + highlightedText = highlightedText.replaceAll(" ", " "); + highlightedText = + HighlightingUtil.replaceHighlightMarkupBy(highlightedText, HIGHLIGHT_START, HIGHLIGHT_END); + + item = new Item(); + item.setTitle(contribution + ";" + artifact); + item.setContents(highlightedText); + + return item; + + } catch (Exception e) { + throw new NotFoundException("Could not highlight artifact: " + e.getMessage(), e); + } + + } + + private Item executeQuery(String query) throws NotFoundException { + + if (!this.domainSearch.indexExists()) { + Contribution[] contributions = this.contributionReader.readContributions(); + + for (Contribution contribution : contributions) { + if (!contribution.getURI().equals(DomainManagerUtil.DEPLOYMENT_CONTRIBUTION_URI)) { + + try { + this.domainSearch.updateContribution(contribution, contribution); + } catch (IndexException e) { + + } + + } + } + } + + Result[] results; + try { + results = this.domainSearch.parseAndSearch(query, true); + } catch (Exception e1) { + throw new NotFoundException("Exception while searching: " + e1.getMessage(), e1); + } + + Item item = new Item(); + item.setTitle("Results"); + + StringWriter sw = new StringWriter(); + this.elementCounter = 0; + + if (results.length > 0) { + for (Result result : results) { + try { + writeToHTML(0, result, sw); + } catch (IOException e) { + // ignore result + } + } + + String contents = HighlightingUtil.replaceHighlightMarkupBy(sw.getBuffer(), HIGHLIGHT_START, HIGHLIGHT_END); + + item.setContents(replaceAll(contents, 40)); + + } else { + item.setContents("No results match: " + query + ""); + } + + // System.out.println(item.getContents()); + + return item; + + } + + private static String replaceAll(CharSequence c, int less) { + StringBuilder sb = new StringBuilder(); + // HashSet set = new HashSet(); + Arrays.sort(characters); + // int start = 0, end = 4; + // char[] chars = new char[end - start]; + // System.arraycopy(characters, start, chars, 0, end - start); + + for (int i = 0; i < c.length(); i++) { + char actual = c.charAt(i); + + // if (Arrays.binarySearch(characters, actual) < 0) { + + // if (actual != '\u000b' && actual != '\u0020' && + // actual != '\u000c' && actual != '\u0009' && + // actual != ')' && actual != '(') { + + if (actual > less || actual == '&' + || actual == '#' + || actual == '\'' + || actual == ' ' + || actual == '%' + || actual == ':' + || actual == '(' + || actual == ')' + || actual == '"') { + + sb.append(actual); + + } else { + // sb.append('0'); + } + + } + + return sb.toString(); + + } + + private static String getIconLocationForResult(Result result) { + + if (SearchFields.COMPONENT_FIELD.equals(result.getField())) { + return "icons/component.png' title='Component"; + + } else if (SearchFields.COMPOSITE_FIELD.equals(result.getField())) { + return "icons/composite.png' title='Composite"; + + } else if (SearchFields.ARTIFACT_FIELD.equals(result.getField())) { + return "icons/artifact.png' title='Artifact"; + } + + return "icons/feed-icon.png"; + + } + + private static void writeResultIcon(Writer writer, Result result) throws IOException { + writer.write(" "); + + } + + private static Result writeFileContentResultToHTML(int indentation, Result result, StringWriter writer) + throws IOException { + + Map contents = result.getContents(); + writeResultIcon(writer, result); + + if (contents.size() == 1 && SearchFields.ARTIFACT_FIELD.equals(contents.values().iterator().next().getField())) { + + writer.write(result.getValue()); + contents = result.getContents(); + + while (contents.size() == 1 && SearchFields.ARTIFACT_FIELD.equals(contents.values().iterator().next() + .getField())) { + + result = contents.values().iterator().next(); + + writer.write(PATH_SEPARATOR); + StringEscapeUtils.escapeHtml(writer, result.getValue()); + + contents = result.getContents(); + + } + + } else { + StringEscapeUtils.escapeHtml(writer, result.getValue()); + } + + return result; + + } + + private static String removeHighlighting(String text) { + return HighlightingUtil.replaceHighlightMarkupBy(text, "", ""); + } + + private static void writeResultName(Result result, StringWriter writer) throws IOException { + + if (SearchFields.CONTRIBUTION_FIELD.equals(result.getField())) { + writer.write(""); + writer.write(StringEscapeUtils.escapeHtml(result.getValue())); + writer.write(""); + + } else if (SearchFields.COMPOSITE_FIELD.equals(result.getField())) { + writer.write(""); + writer.write(StringEscapeUtils.escapeHtml(result.getValue())); + writer.write(""); + + } else { + StringEscapeUtils.escapeHtml(writer, result.getValue()); + } + + } + + private static String getContributionURI(Result result) { + + if (result == null) { + return ""; + + } else if (SearchFields.CONTRIBUTION_FIELD.equals(result.getField())) { + return removeHighlighting(result.getValue()); + + } else { + return getContributionURI(result.getContainer()); + } + + } + + private void writeToHTML(int indentation, Result result, StringWriter writer) throws IOException { + + startIndentation(indentation++, writer); + String field = result.getField(); + + if (SearchFields.FILE_CONTENT_FIELD.equals(field)) { + String content = result.getValue(); + + if (content != null && content.length() > 0 && DomainSearchFormatter.isHighlighted(content)) { + String contributionPlusArtifact = + getContributionURI(result) + ";" + removeHighlighting(result.getContainer().getValue()); + + writer.write(HTML_NEW_LINE); + + this.elementCounter++; + writer.write("
"); + writer.write("

"); + // + "view all  view all  "); + + writer.write("download

"); + + int i = 0; + while (i < content.length()) { + StringEscapeUtils.escapeHtml(writer, content.substring(i, Math.min(i + MAX_CONTENT_LINE_WIDTH, + content.length()))); + writer.write(HTML_NEW_LINE); + i += MAX_CONTENT_LINE_WIDTH; + } + + writer.write("
"); + writer.write("
"); + + } + + } else if (SearchFields.ARTIFACT_FIELD.equals(field)) { + result = writeFileContentResultToHTML(indentation, result, writer); + } else { + writeResultIcon(writer, result); + writeResultName(result, writer); + } + + endIndentation(writer); + + for (Result actualResult : result.getContents().values()) { + writeToHTML(indentation, actualResult, writer); + } + } + + public Entry[] getAll() { + System.out.println("getAll"); + return null; + } + + public String post(String key, Item item) { + System.out.println("post"); + return null; + } + + public void put(String key, Item item) throws NotFoundException { + System.out.println("put"); + } + + @SuppressWarnings("unchecked") + public Entry[] query(String queryString) { + + try { + + Item item; + String key; + + if (queryString.startsWith("highlight")) { + int lastSemicolonIndex = queryString.lastIndexOf(";"); + String artifact = queryString.substring(lastSemicolonIndex + 1); + int secondLastSemicolonIndex = queryString.lastIndexOf(";", lastSemicolonIndex - 1); + String contribution = queryString.substring(secondLastSemicolonIndex + 1, lastSemicolonIndex); + String query = queryString.substring("highlight".length(), secondLastSemicolonIndex); + + item = highlightArtifact(contribution, artifact, query); + key = queryString.substring("highlight".length()); + + } else if (queryString.startsWith("query")) { + key = queryString.substring("query".length()); + item = executeQuery(key); + + } else { + throw new NotFoundException("Invalid operation!"); + } + + Entry[] returnArray = new Entry[1]; + returnArray[0] = new Entry(key, item); + + return returnArray; + + } catch (Exception t) { + return new Entry[0]; + } + + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/launcher/DomainManagerLauncherBootstrap.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/launcher/DomainManagerLauncherBootstrap.java new file mode 100644 index 0000000000..1bb117f385 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/java/org/apache/tuscany/sca/domain/manager/launcher/DomainManagerLauncherBootstrap.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.launcher; + +import org.apache.tuscany.sca.domain.manager.impl.DomainManagerConfiguration; +import org.apache.tuscany.sca.node.SCAClient; +import org.apache.tuscany.sca.node.SCANode; +import org.apache.tuscany.sca.node.SCANodeFactory; + +/** + * Bootstrap class for the SCA domain manager. + * + * @version $Rev$ $Date$ + */ +public class DomainManagerLauncherBootstrap { + private SCANode node; + + /** + * A node wrappering an instance of a domain manager. + */ + public static class NodeFacade implements SCANode { + private ClassLoader threadContextClassLoader; + private ClassLoader runtimeClassLoader; + private SCANode node; + private String rootDirectory; + + private NodeFacade(String rootDirectory) { + this.rootDirectory = rootDirectory; + runtimeClassLoader = Thread.currentThread().getContextClassLoader(); + } + + public void start() { + threadContextClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(runtimeClassLoader); + SCANodeFactory factory = SCANodeFactory.newInstance(); + node = factory.createSCANodeFromClassLoader("DomainManager.composite", getClass().getClassLoader()); + node.start(); + + // Set the domain manager's root directory + DomainManagerConfiguration domainManagerConfiguration = ((SCAClient) node).getService(DomainManagerConfiguration.class, "DomainManagerConfigurationComponent"); + domainManagerConfiguration.setRootDirectory(rootDirectory); + } finally { + Thread.currentThread().setContextClassLoader(threadContextClassLoader); + } + } + + public void stop() { + try { + Thread.currentThread().setContextClassLoader(runtimeClassLoader); + node.stop(); + } finally { + Thread.currentThread().setContextClassLoader(threadContextClassLoader); + } + } + } + + /** + * Constructs a new domain manager bootstrap. + */ + public DomainManagerLauncherBootstrap(String rootDirectory) throws Exception { + node = new NodeFacade(rootDirectory); + } + + /** + * Returns the node representing the domain manager. + * @return + */ + public SCANode getNode() { + return node; + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/DomainManager.composite b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/DomainManager.composite new file mode 100644 index 0000000000..5e55c20fbc --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/DomainManager.composite @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + workspace.xml + cloud + + + + + + + + + + + + + + + + + + files + + + + + + + + + files + + + + + + + + + + domain.composite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cloud.composite + cloud + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + domainSearchIndex + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud-gadget.html new file mode 100644 index 0000000000..36488c1a01 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud-gadget.html @@ -0,0 +1,409 @@ + + + +SCA Domain - Cloud + + + + + + + + +
+ +
+
+
+ >Add +  Delete +    + Start +  Stop +
+ + + +
+ + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud.html new file mode 100644 index 0000000000..d661d5d38b --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/cloud.html @@ -0,0 +1,68 @@ + + + +SCA Domain - Cloud + + + + + + + +
+
+ + + SCA Domain

+ Cloud
  +
+
+ Here is the list of SCA nodes configured in your SCA domain cloud. +

+ +
+ + + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite-gadget.html new file mode 100644 index 0000000000..3af9c3f725 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite-gadget.html @@ -0,0 +1,278 @@ + + + +SCA Domain - Domain Composite + + + + + + + + +
+ +
+
+
+ >Add +  Delete +
+ + + +
+ + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite.html new file mode 100644 index 0000000000..b0631e1d66 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/composite.html @@ -0,0 +1,66 @@ + + + +SCA Domain - Domain Composite + + + + + + + +
+
+ + + SCA Domain

+ Domain Composite  +
+
+ Here is the list of SCA composites currently included as top-level composites in your SCA domain. +

+ +
+ + + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files-gadget.html new file mode 100644 index 0000000000..7ddc923223 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files-gadget.html @@ -0,0 +1,124 @@ + + + +SCA Domain - Contribution File Server + + + + + + + + +
+ +
+
+
+ >Upload +  Delete +
+ + + +
+ + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files.html new file mode 100644 index 0000000000..37d89e7665 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/files.html @@ -0,0 +1,64 @@ + + + +SCA Domain - Contribution File Server + + + + + + + +
+
+ + + SCA Domain

+ File Server  +
+
+ This is a simple ATOM-based file server useful to share files if you don't have an FTP, SVN or Maven repository. +

+ +
+ + + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home-gadget.html new file mode 100644 index 0000000000..e54626af0e --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home-gadget.html @@ -0,0 +1,36 @@ + + + +SCA Domain - Home + + + + + + + + +
+ + +
+ + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home.html new file mode 100644 index 0000000000..141a48a690 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/home.html @@ -0,0 +1,62 @@ + + + +SCA Domain - Home + + + + + + + +
+
+ + + SCA Domain + +





+ +
+ + + + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/artifact.png b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/artifact.png new file mode 100644 index 0000000000..dddbebd2bd Binary files /dev/null and b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/artifact.png differ diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/component.png b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/component.png new file mode 100644 index 0000000000..7315475b3e Binary files /dev/null and b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/component.png differ diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/composite.png b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/composite.png new file mode 100644 index 0000000000..3fa9d02549 Binary files /dev/null and b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/composite.png differ diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/feed-icon.png b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/feed-icon.png new file mode 100644 index 0000000000..a59728b2ad Binary files /dev/null and b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/icons/feed-icon.png differ diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/manager.css b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/manager.css new file mode 100644 index 0000000000..e080ff1d87 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/manager.css @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +body { + white-space: nowrap; margin: 2px; +} + +table { + border: 1px; border-collapse: separate +} + +th { + font-weight: bold; white-space: nowrap; background-color: #e5ecf9; color: #598edd; + text-align: left; padding-left: 2px; padding-right: 20px; padding-top: 2px; padding-bottom: 2px; vertical-align: text-top; + border-top: 1px; border-bottom: 1px; border-left: 0px; border-right: 0px; + border-style: solid; border-top-color: #a2bae7; border-bottom-color: #d1d3d4 +} + +td { + padding-left: 2px; padding-top: 2px; padding-right: 20px; white-space: nowrap; vertical-align: text-top +} + +iframe { + visibility: hidden; +} + +input { + vertical-align: middle +} + +a:link { + color: blue +} + +a:visited { + color: blue +} + +.tdw { + padding-left: 2px; padding-top: 2px; padding-right: 20px; white-space: normal; vertical-align: text-top +} + +.hd1 { + font-size:150%; font-weight: bold +} + +.tbar { + margin: 0px; + padding-top: 0px; padding-left: 0px; padding-right: 0px; padding-bottom: 3px; + border-bottom: 1px solid #a2bae7 +} + +.ltbar { + padding-left: 0px; padding-top: 0px; padding-right: 20px; white-space: nowrap; vertical-align: top +} + +.rtbar { + padding-left: 0px; padding-right: 0px; padding-top: 0px; white-space: nowrap; vertical-align: top; + text-align: right +} + +.suggest { + background-color: #e5ecf9; color: #598edd; + border-top: 1px; border-bottom: 1px; border-left: 1px; border-right: 1px; + border-style: solid; border-top-color: #a2bae7; border-bottom-color: #d1d3d4; + border-left-color: #d1d3d4; border-right-color: #d1d3d4; + position: absolute; + overflow: auto; overflow-x: hidden; + cursor: default; + padding: 0px; margin: 0px; +} + +suggestTable { + border: 0px; border-collapse: separate; + padding-left: 5px; padding-right: 5px; padding-top: 2px; padding-bottom: 2px; + margin: 0px; +} + +.suggestItem { + padding-left: 2px; padding-top: 0px; padding-bottom: 0px; padding-right: 2px; white-space: nowrap; vertical-align: text-top; + background-color: #e5ecf9; color: #598edd; +} + +.suggestHilighted { + padding-left: 2px; padding-top: 0px; padding-bottom: 0px; padding-right: 2px; white-space: nowrap; vertical-align: text-top; + background-color: #598edd; color: #e5ecf9; +} + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search-gadget.html new file mode 100644 index 0000000000..24a7013cf7 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search-gadget.html @@ -0,0 +1,100 @@ + + + + + +SCA Domain - Domain Composite + + + + + + + + + + + +
+ + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search.html new file mode 100644 index 0000000000..376e44726f --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/search.html @@ -0,0 +1,127 @@ + + + +SCA Domain - Search + + + + + + + + + + + +
+
+ + + Results
+
+ +

+

+

+ +
+ + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/toolbar-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/toolbar-gadget.html new file mode 100644 index 0000000000..d145fde1c4 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/toolbar-gadget.html @@ -0,0 +1,59 @@ + + + +SCA Domain - Toolbar + + + + + + + +
+ + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/utils.js b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/utils.js new file mode 100644 index 0000000000..d41435b084 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/utils.js @@ -0,0 +1,248 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Autocomplete / suggest support for input fields + * + * To use it declare a 'suggest' function as follows: + * function suggestItems() { + * return new Array('abc', 'def', 'ghi'); + * } + * + * then hook it to an input field as follows: + * suggest(document.yourForm.yourInputField, suggestItems); + */ +function selectSuggestion(node, value) { + for (;;) { + node = node.parentNode; + if (node.tagName.toLowerCase() == 'div') { + break; + } + } + node.selectSuggestion(value); +} + +function hilightSuggestion(node, over) { + if (over) { + node.className = 'suggestHilighted'; + } else { + node.className = 'suggestItem'; + } +} + +function suggest(input, suggestFunction) { + + input.suggest = suggestFunction; + + input.selectSuggestion = function(value) { + this.hideSuggestDiv(); + this.value = value; + } + + input.hideSuggestDiv = function() { + if (this.suggestDiv != null) { + this.suggestDiv.style.visibility = 'hidden'; + } + } + + input.showSuggestDiv = function() { + if (this.suggestDiv == null) { + this.suggestDiv = document.createElement('div'); + this.suggestDiv.input = this; + this.suggestDiv.className = 'suggest'; + input.parentNode.insertBefore(this.suggestDiv, input); + this.suggestDiv.style.visibility = 'hidden'; + this.suggestDiv.style.zIndex = '99'; + + this.suggestDiv.selectSuggestion = function(value) { + this.input.selectSuggestion(value); + } + } + + var values = this.suggest(); + var items = ""; + for (var i = 0; i < values.length; i++) { + if (values[i].indexOf(this.value) == -1) { + continue; + } + if (items.length == 0) { + items += ''; + } + items += ''; + } + if (items.length != 0) { + items += '
' + values[i] + '
'; + } + this.suggestDiv.innerHTML = items; + + if (items.length != 0) { + var node = input; + var left = 0; + var top = 0; + for (;;) { + left += node.offsetLeft; + top += node.offsetTop; + node = node.offsetParent; + if (node.tagName.toLowerCase() == 'body') { + break; + } + } + this.suggestDiv.style.left = left; + this.suggestDiv.style.top = top + input.offsetHeight; + this.suggestDiv.style.visibility = 'visible'; + } else { + this.suggestDiv.style.visibility = 'hidden'; + } + } + + input.onkeydown = function(event) { + this.showSuggestDiv(); + }; + + input.onkeyup = function(event) { + this.showSuggestDiv(); + }; + + input.onmousedown = function(event) { + this.showSuggestDiv(); + }; + + input.onblur = function(event) { + setTimeout(function() { input.hideSuggestDiv(); }, 50); + }; +} + +/** + * A Toolbar class + */ +function Tool(name, href) { + this.name = name; + this.href = href; +} + +Tool.prototype.print = function() { + var loc = '' + location; + if (loc.match(this.href) == null) { + return '' + this.name + ''; + } else { + return '' + this.name + ''; + } +} + +/** + * Initialize the toolbar + */ +function toolbar(home, tools) { + var toolbar = '' + + '' + + '' + + '
'; + + for (var i = 0; i < tools.length; i++) { + toolbar = toolbar + '' + } + + toolbar = toolbar + '' + + toolbar = toolbar + '
' +tools[i].print() + ' 
' + + '
' + home.print() + '
'; + + return toolbar; +} + +/** + * Return an non-sparse array from an array or an object. + */ +function array(obj) { + if (obj.length == undefined) { + var a = new Array(); + a[0] = obj; + return a; + } + else { + var a = new Array(); + var n = 0; + for (var i in obj) { + a[n++] = obj[i]; + } + return a; + } +} + +/** + * Dump a Javascript object to the console + */ +function dump(o) { + for (f in o) { + try { + console.log(f + '=' + o[f]); + } catch (e) {} + } +} + +/** + * Return the content document of the given window. + */ +function content(win) { + if (win.document != 'undefined' && win.document != null) { + return win.document; + } else if (win.contentDocument != 'undefined' && win.contentDocument != null) { + return win.contentDocument; + } else { + return null; + } +} + +/** + * Returns a child element with the given id. + */ +function elementByID(node, id) { + for (var i in node.childNodes) { + var child = node.childNodes[i]; + if (child.id == id) { + return child; + } else { + child = elementByID(child, id); + if (child != null) { + return child; + } + } + } + return null; +} + +/** + * Install a gadget. + */ +function gadget(win, doc) { + var ongadget = null; + try { + if (win.parent.ongadget != null && win.parent.ongadget != 'undefined') { + ongadget = win.parent.ongadget; + } + } catch (e) { + } + if (ongadget != null) { + return ongadget(win, doc); + } else { + return doc; + } +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace-gadget.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace-gadget.html new file mode 100644 index 0000000000..3b8a32c940 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace-gadget.html @@ -0,0 +1,232 @@ + + + +SCA Domain - Contributions + + + + + + + + +
+ +
+
+
+ >Add +  Delete +
+ + + +
+ + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace.html b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace.html new file mode 100644 index 0000000000..36c02ab1e6 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/main/resources/workspace.html @@ -0,0 +1,65 @@ + + + +SCA Domain - Contributions + + + + + + + +
+
+ + + SCA Domain

+ Contributions
  +
+ Here is the list of SCA contributions currently available in your SCA domain. +

+ +
+ + + + + + + diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerTestCase.java b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerTestCase.java new file mode 100644 index 0000000000..5e76556a14 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/java/org/apache/tuscany/sca/domain/manager/impl/DomainManagerTestCase.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.tuscany.sca.domain.manager.impl; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.URL; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.data.collection.Entry; +import org.apache.tuscany.sca.data.collection.Item; +import org.apache.tuscany.sca.data.collection.NotFoundException; + +/** + * Test case for the workspace admin services. + * + * @version $Rev$ $Date$ + */ +public class DomainManagerTestCase extends TestCase { + + private ContributionCollectionImpl contributionCollection; + private DeployableCompositeCollectionImpl deployableCollection; + private DomainManagerConfigurationImpl domainManagerConfiguration; + + private static final String WORKSPACE_XML = + "\n" + + "\n" + + ""; + + @Override + protected void setUp() throws Exception { + ClassLoader cl = getClass().getClassLoader(); + + // Make sure we start with a clean workspace.xml file + URL url = cl.getResource("workspace.xml"); + FileOutputStream os = new FileOutputStream(new File(url.toURI())); + Writer writer = new OutputStreamWriter(os); + writer.write(WORKSPACE_XML); + writer.flush(); + writer.close(); + + // Create a workspace collection component + domainManagerConfiguration = new DomainManagerConfigurationImpl(); + domainManagerConfiguration.initialize(); + String root = url.getFile(); + root = root.substring(0, root.lastIndexOf('/')); + domainManagerConfiguration.setRootDirectory(root); + + contributionCollection = new ContributionCollectionImpl(); + contributionCollection.domainManagerConfiguration = domainManagerConfiguration; + contributionCollection.workspaceFile = "workspace.xml"; + contributionCollection.deploymentContributionDirectory = "cloud"; + contributionCollection.domainManagerConfiguration = domainManagerConfiguration; + deployableCollection = new DeployableCompositeCollectionImpl(); + deployableCollection.domainManagerConfiguration = domainManagerConfiguration; + deployableCollection.contributionCollection = contributionCollection; + contributionCollection.initialize(); + deployableCollection.initialize(); + + // Populate the workspace with test data + Item item = new Item(); + item.setLink(cl.getResource("contributions/store").toString()); + contributionCollection.post("store", item); + item.setLink(cl.getResource("contributions/assets").toString()); + contributionCollection.post("assets", item); + } + + public void testGetAll() { + Entry[] entries = contributionCollection.getAll(); + assertEquals(2, entries.length); + assertEquals(entries[0].getKey(), "store"); + } + + public void testGet() throws NotFoundException { + Item item = contributionCollection.get("assets"); + assertTrue(item.getAlternate().endsWith("contributions/assets/")); + } + + public void testDependencies1() { + Entry[] entries = contributionCollection.query("alldependencies=store"); + assertEquals(2, entries.length); + } + + public void testDependencies2() { + Entry[] entries = contributionCollection.query("alldependencies=assets"); + assertEquals(1, entries.length); + assertEquals("assets", entries[0].getKey()); + } + + public void testDeployables() throws NotFoundException { + Entry[] entries = deployableCollection.getAll(); + assertEquals(1, entries.length); + assertEquals("composite:store;http://store;store", entries[0].getKey()); + } + +} diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/assets/META-INF/sca-contribution.xml b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/assets/META-INF/sca-contribution.xml new file mode 100644 index 0000000000..e96d97312e --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/assets/META-INF/sca-contribution.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/store/META-INF/sca-contribution.xml b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/store/META-INF/sca-contribution.xml new file mode 100644 index 0000000000..794bfae98a --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/contributions/store/META-INF/sca-contribution.xml @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/workspace.xml b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/workspace.xml new file mode 100644 index 0000000000..e6ac7d7701 --- /dev/null +++ b/sca-java-1.x/tags/1.6.1/modules/domain-manager/src/test/resources/workspace.xml @@ -0,0 +1,21 @@ + + + + -- cgit v1.2.3