/* * Copyright 2012 SAP AG * * 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. */ package com.sap.research.connectivity.gw; import java.io.File; import java.io.IOException; import java.util.logging.Logger; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.osgi.service.component.ComponentContext; import org.springframework.roo.model.JavaType; import org.springframework.roo.shell.CliAvailabilityIndicator; import org.springframework.roo.shell.CliCommand; import org.springframework.roo.shell.CliOption; import org.springframework.roo.shell.CommandMarker; import org.springframework.roo.shell.converters.StaticFieldConverter; /** * Example of a command class. The command class is registered by the Roo shell following an * automatic classpath scan. You can provide simple user presentation-related logic in this * class. You can return any objects from each method, or use the logger directly if you'd * like to emit messages of different severity (and therefore different colors on * non-Windows systems). * * @since 1.1.1 */ @Component // Use these Apache Felix annotations to register your commands class in the Roo container @Service public class GwCommands implements CommandMarker { // All command types must implement the CommandMarker interface /** * Get hold of a JDK Logger */ private Logger log = Logger.getLogger(getClass().getName()); /** * Get a reference to the GwOperations from the underlying OSGi container */ @Reference private GwOperations operations; /** * Get a reference to the StaticFieldConverter from the underlying OSGi container; * this is useful for 'type save' command tab completions in the Roo shell */ @Reference private StaticFieldConverter staticFieldConverter; /** * The activate method for this OSGi component, this will be called by the OSGi container upon bundle activation * (result of the 'addon install' command) * * @param context the component context can be used to get access to the OSGi container (ie find out if certain bundles are active) */ protected void activate(ComponentContext context) { } /** * The deactivate method for this OSGi component, this will be called by the OSGi container upon bundle deactivation * (result of the 'addon remove' command) * * @param context the component context can be used to get access to the OSGi container (ie find out if certain bundles are active) */ protected void deactivate(ComponentContext context) { } /* * SAP Research GW Connectivity Commands */ /** * Check if connectivity setup command is available */ @CliAvailabilityIndicator("gateway setup") public boolean isAddODataConnectivityCommandAvailable() { //Check that project is created and Persistence is set up return operations.isCommandGWSetupAvailable(); } /** * Check if defining an odata endpoint command is available */ @CliAvailabilityIndicator("gateway define odata_endpoint") public boolean isAddODataEndpointCommandAvailable() { //Check that project is created and Persistence is set up return operations.isCommandODataEndpointAvailable(); } /** * Check if gateway entity command is available */ @CliAvailabilityIndicator("gateway entity") public boolean isAddGwEntityCommandAvailable() { //Check that project is created and Persistence is set up return operations.isCommandGWEntityAvailable(); } /** * Check if connectivity gateway field / gateway local field commands are available */ @CliAvailabilityIndicator({"gateway field", "gateway local field"}) public boolean isAddGwFieldCommandAvailable() { //Check that there is a gateway entity available boolean returnResults = false; try { returnResults = operations.isCommandGWFieldAvailable(); } catch (IOException e) { log.severe("The \"gateway field\" command is not available at the moment. Please check the attached error."); e.printStackTrace(); } return returnResults; } /** * Check if gateway mvc adapt command is available */ @CliAvailabilityIndicator("gateway mvc adapt") public boolean isGWMVCAdaptCommandAvailable() { boolean returnResults = false; try { returnResults = operations.isCommandGWMVCAdaptCommandAvailable(); } catch (IOException e) { log.severe("The \"gateway mvc adapt\" command is not available at the moment. Please check the attached error."); e.printStackTrace(); } return returnResults; } /** * Add Gateway Connectivity to the project */ @CliCommand(value = "gateway setup", help="Add a class for handling OData Gateway Connectivity.") public void addODataConnectivity() { operations.addODataConnectivity(); } /** * Define connectivity namespace */ @CliCommand(value = "gateway define odata_endpoint", help="Define a namespace for a connection.") public void addGWNamespace( @CliOption(key = "Name", mandatory = true, help = "Connection Name") String nsName, @CliOption(key = "URL", mandatory = true, help = "OData Endpoint URL") String url, @CliOption(key = "USER", mandatory = true, help = "Username") String user, @CliOption(key = "PASSWORD", mandatory = true, help = "Password") String pass, @CliOption(key = "CSRF_MODE", mandatory = false, unspecifiedDefaultValue = "standard", specifiedDefaultValue = "standard", help = "The Gateway Server Mode for CSRF. Default is standard. For compatibility mode, choose compatibility.") final String csrfMode, @CliOption(key = "HTTP_PROXYHOST", mandatory = false, help = "http.proxyhost", unspecifiedDefaultValue = "") String http_proxyhost, @CliOption(key = "HTTP_PROXYPORT", mandatory = false, help = "http.proxyport", unspecifiedDefaultValue = "") String http_proxyport, @CliOption(key = "TIMEOUT_CALL", mandatory = false, unspecifiedDefaultValue = "30", specifiedDefaultValue = "30", help = "The timeout for retrieving the metadata in seconds. Default is 30.") int timeout ) { //Prerequisite validation: Check if the metadata jar is placed at the right location. String metadataExtractorPath = System.getProperty("user.home") + File.separatorChar + "appToRetrieveOdataMetadata.jar"; File metadataExtractorJar = new File(metadataExtractorPath); if(!metadataExtractorJar.exists()){ log.severe("The metadata extractor JAR is missing in the user-home directory"); return; } try { operations.addNamespace(nsName, url, user, pass, csrfMode, http_proxyhost, http_proxyport, timeout); log.info("An XML file containing metadata retrieved from the Gateway service has been generated."); log.info("Please check the " + nsName + "_metadata.xml file from the connectivity package for available entities and fields."); } catch (Exception e) { log.severe(e.getMessage()); } } /** * Create a gw connected entity */ @CliCommand(value = "gateway entity", help="Creates a local class connected to the specified OData Service Provider.") public void addClassGwConnectivity( @CliOption(key = "namespace", optionContext = "connectivity", mandatory = true, help = "OData Endpoint URL") final GwEndpoint endPointName, @CliOption(key = "remoteEntitySet", mandatory = true, help = "OData Entity Set Name") final GwRemoteEntity remoteEntitySet, @CliOption(key = "import_all", mandatory = false, unspecifiedDefaultValue = "true", specifiedDefaultValue = "true", help = "Whether to import all fields from the remote entity") final boolean importAll, @CliOption(key = "import_associations", mandatory = false, unspecifiedDefaultValue = "false", specifiedDefaultValue = "true", help = "Whether to import associations of the remote entity. Please note that the associated entities must be created beforehand!") final boolean importAssociations ) { // Create a class with JPA specific annotations try { operations.createEntity(endPointName.getName(), remoteEntitySet.getName()); // Add fields, getter/setters and persistence methods operations.addFieldsMethodsAndRelations(endPointName.getName(), remoteEntitySet.getName(), importAll, importAssociations); } catch (Exception e) { log.severe(e.getMessage()); } } /** * Import a remote field from a gateway connected entity */ @CliCommand(value = "gateway field", help="Imports a specific field from the specified remote gateway entity.") public void addGwField( @CliOption(key = "entityClass", mandatory = true, help = "Name of the linked entity", optionContext = "domain") final GwEntityClass localClassName, @CliOption(key = "fieldName", mandatory = false, help = "Field to be imported") final GwField fieldName ) { try { operations.addRemoteFieldInGWClass(localClassName.getName(), fieldName.getName()); } catch (Exception e) { log.severe(e.getMessage()); e.printStackTrace(); } } /** * Create a local field related to a gateway connected entity */ @CliCommand(value = "gateway local field", help="Create a local field in an entity which is connected to the gateway. " + "The created field will be only available locally.") public void addLocalGwField( @CliOption(key = "entityClass", mandatory = true, help = "Name of the linked entity", optionContext = "domain") final GwEntityClass localClassName, @CliOption(key = "fieldName", mandatory = true, help = "Field to be created") final String fieldName, @CliOption(key = "fieldType", mandatory = true, optionContext = "java-lang,java-date", help = "The type of the entity") final JavaType fieldType ) { try { operations.addLocalFieldInGWClass(localClassName.getName(), fieldName, fieldType); } catch (Exception e) { log.severe(e.getMessage()); e.printStackTrace(); } } /** * Adapt the controllers to gateway connected entity */ @CliCommand(value = "gateway mvc adapt", help="It adapts the controllers of the GW connected entities in order to make all the CRUD operations work. " + "This command is needed ONLY for the entities having local fields mingled with remote ones.") public void adaptMVC( @CliOption(key = "entityClass", mandatory = true, help = "Name of the linked entity", optionContext = "domain") final GwEntityClass localClassName ) { try { // Modify the controller (because we need to overwrite the show method) operations.modifyController(localClassName.getName()); } catch (Exception e) { log.severe(e.getMessage()); e.printStackTrace(); } } }