Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EclipseLink/Development/DBWS/OSGi/AdvCustIIAutoGen
Advanced Customization - Part II: Auto-generation of EclipseLink metadata
The files under META-INF and wsdl (eclipselink-dbws.xml, eclipselink-dbws-or.xml, etc.) can be generated at runtime when the Activator is first initialized. Starting with EclipseLink 2.1.2, portions of the initialization of org.eclipse.persistence.internal.dbws.ProviderHelper
can be sub-classed:
protected InputStream initXRServiceStream(ClassLoader parentClassLoader, ServletContext sc) { ... protected InputStream initXRSchemaStream(ClassLoader parentClassLoader, ServletContext sc) { ... protected InputStream initWSDLInputStream(ClassLoader parentClassLoader, ServletContext sc) { ....
From the EclipseLink installation, add eclipselink-dbwsutils.jar and javax.wsdl_1.6.2.v200806030405.jar to the SimpleTable project, under a lib dir:
Open the MANIFEST.MF file in the 'Plug-in Manifest Editor' and select the 'Runtime' tab and add the above jars to the plug-in's classpath:
The wsdl directory can be removed, along with all the DBWS files under META-INF (the project no longer needs these directories to be 'src' directories).
DBWSBuilder
is normally invoked as a command-line tool along with a file containing 'operations' that are converted to DBWS runtime artifacts (eclipselink-dbws.xml, eclipselink-dbws-or.xml, etc.) It is also possible to program an instance of DBWSBuilder
:
.... additional constants //database properties public static final String DATABASE_URL = "jdbc:derby:test;create=true"; public static final String DATABASE_DRIVER = "org.apache.derby.jdbc.EmbeddedDriver"; public static final String DATABASE_PLATFORM = "org.eclipse.persistence.platform.database.DerbyPlatform"; ... additional imports in simpletable.Activator //EclipseLink imports import org.eclipse.persistence.internal.databaseaccess.Platform; import org.eclipse.persistence.internal.dbws.ProviderHelper; import org.eclipse.persistence.internal.helper.ConversionManager; import org.eclipse.persistence.internal.xr.ProjectHelper; import org.eclipse.persistence.internal.xr.XRDynamicClassLoader; import org.eclipse.persistence.logging.SessionLog; import org.eclipse.persistence.oxm.XMLContext; import org.eclipse.persistence.oxm.XMLLogin; import org.eclipse.persistence.sessions.DatabaseLogin; import org.eclipse.persistence.sessions.DatabaseSession; import org.eclipse.persistence.sessions.DatasourceLogin; import org.eclipse.persistence.sessions.Project; import org.eclipse.persistence.sessions.Session; import org.eclipse.persistence.sessions.factories.XMLProjectReader; import org.eclipse.persistence.tools.dbws.DBWSBuilder; import org.eclipse.persistence.tools.dbws.JavasePackager; import org.eclipse.persistence.tools.dbws.TableOperationModel; import static org.eclipse.persistence.logging.AbstractSessionLog.translateStringToLoggingLevel; import static org.eclipse.persistence.tools.dbws.DBWSBuilder.NO_SESSIONS_FILENAME; import static org.eclipse.persistence.tools.dbws.DBWSBuilder.SESSIONS_FILENAME_KEY; import static org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse.noArchive; import static org.eclipse.persistence.tools.dbws.XRPackager.__nullStream; ... additional member variables in simpletable.Activator private static DBWSBuilder builder = new DBWSBuilder(); private static ByteArrayOutputStream DBWS_SERVICE_STREAM = new ByteArrayOutputStream(); private static ByteArrayOutputStream DBWS_SCHEMA_STREAM = new ByteArrayOutputStream(); private static ByteArrayOutputStream DBWS_OR_STREAM = new ByteArrayOutputStream(); private static ByteArrayOutputStream DBWS_OX_STREAM = new ByteArrayOutputStream(); private static ByteArrayOutputStream DBWS_WSDL_STREAM = new ByteArrayOutputStream(); ... additional setup required when bundle starts public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; builder.quiet = true; //set properties builder.setProjectName("simpletable"); builder.setLogLevel(SessionLog.FINE_LABEL); builder.setDriver(DATABASE_DRIVER); builder.setPlatformClassname(DATABASE_PLATFORM); builder.setUrl(DATABASE_URL); builder.getProperties().put(SESSIONS_FILENAME_KEY, NO_SESSIONS_FILENAME); TableOperationModel tModel = new TableOperationModel(); tModel.setName("simpleTable"); tModel.setTablePattern("SIMPLETABLE"); builder.getOperations().add(tModel); JavasePackager packager = new JavasePackager() { @Override public void start() { // normally start() checks for the existence of a temp directory - // no need since all DBWSBuilder artifacts are in-memory } }; packager.setArchiveUse(noArchive); builder.setPackager(packager); try { // can't go thru java.sql.DriverManager 'cause it uses Class.forName() - not OSGi-friendly Driver driver = new org.apache.derby.jdbc.EmbeddedDriver(); Connection conn = driver.connect(DATABASE_URL, null); builder.setConnection(conn); } catch (Exception e) { // find out what happened e.printStack(); throw e; } builder.build(DBWS_SCHEMA_STREAM, __nullStream, DBWS_SERVICE_STREAM, DBWS_OR_STREAM, DBWS_OX_STREAM, __nullStream, __nullStream, DBWS_WSDL_STREAM, __nullStream, __nullStream, __nullStream, __nullStream, null); super.init(this.getClass().getClassLoader(), null, false); // regular setup of Endpoint endpoint = Endpoint.create(this); endpoint.publish(ENDPOINT_ADDRESS); ....
The call to super.init(XRDynamicClassLoader, null, false)
makes callbacks to the three init
routines mentioned above where we return the information computed in builder.build(DBWS_SCHEMA_STREAM,...)
:
protected InputStream initXRServiceStream(ClassLoader parentClassLoader, ServletContext sc) { return new ByteArrayInputStream(DBWS_SERVICE_STREAM.toByteArray()); } protected InputStream initXRSchemaStream(ClassLoader parentClassLoader, ServletContext sc) { return new ByteArrayInputStream(DBWS_SCHEMA_STREAM.toByteArray()); } protected InputStream initWSDLInputStream(ClassLoader parentClassLoader, ServletContext sc) { return new ByteArrayInputStream(DBWS_WSDL_STREAM.toByteArray()); }
buildSessions()
(looks complicated but its just 'plumbing'): ... import static org.eclipse.persistence.logging.AbstractSessionLog.translateStringToLoggingLevel; ... @Override public void buildSessions() { XRDynamicClassLoader xrdecl = new XRDynamicClassLoader(parentClassLoader); Project oxProject = XMLProjectReader.read(new StringReader(DBWS_OX_STREAM.toString()), xrdecl); ((XMLLogin)oxProject.getDatasourceLogin()).setEqualNamespaceResolvers(false); Project orProject = XMLProjectReader.read(new StringReader(DBWS_OR_STREAM.toString()), xrdecl); DatasourceLogin login = orProject.getLogin(); ((DatabaseLogin)login).setConnectionString(builder.getUrl()); ((DatabaseLogin)login).setDriverClassName(builder.getDriver()); Platform platform = builder.getDatabasePlatform(); ConversionManager cm = platform.getConversionManager(); cm.setLoader(xrdecl); login.setDatasourcePlatform(platform); ((DatabaseLogin)login).bindAllParameters(); orProject.setDatasourceLogin(login); ProjectHelper.fixOROXAccessors(orProject, oxProject); DatabaseSession databaseSession = orProject.createDatabaseSession(); int logLevel = translateStringToLoggingLevel(builder.getLogLevel()); if (SessionLog.OFF == logLevel) { databaseSession.dontLogMessages(); } else { databaseSession.setLogLevel(logLevel); } xrService.setORSession(databaseSession); xrService.setXMLContext(new XMLContext(oxProject)); xrService.setOXSession(xrService.getXMLContext().getSession(0)); }