Custom xml validation inside eclipse plugin with Custom Validator? - eclipse-plugin

I want to validate a custom content type document(xml kind), with an custom validator. Want to validate it with a xsd, but only after certain preprocessing of main document.
Normal xml validator can't be used because-
1.) The schema location(xsd) & namespaces are not defined in the main document file.
2.) And bcz of first reason & many more, want to do some preprocessing to the document file, before applying xsd validation.
So I want to use the xml validator, but only after preprocessing of my file.
My plugin.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.core.runtime.contentTypes">
<content-type
id="com.xyz.ide.core.contentType.dummy"
base-type="org.eclipse.core.runtime.xml"
file-extensions="blabla"
/>
</extension>
<extension
point="org.eclipse.wst.sse.ui.sourcevalidation">
<validator
scope="total"
class="mc.CustomValidator"
id="com.xyz.myValidator">
<contentTypeIdentifier
id="com.xyz.ide.core.contentType.dummy">
<partitionType
id="org.eclipse.wst.xml.XML_DEFAULT">
</partitionType>
</contentTypeIdentifier>
</validator>
</extension>
</plugin>
CustomValidator.java
public class CustomValidator implements ISourceValidator, IValidator {
XMLValidator validator = new XMLValidator();
IDocument document;
public void validate(IValidationContext helper, IReporter reporter) {
String fileContent = this.document.get();
final InputStream is = new ByteArrayInputStream(fileContent.toLowerCase().getBytes());
// Whats the problem in this line???
XMLValidationReport report = validator.validate("/home/rchawla/xmlWorkspace/abc.xsd", is);
ValidationMessage[] messages = report.getValidationMessages();
for(ValidationMessage message:messages){
System.out.println(message.getMessage());
}
}
I can hit the validate method on running the plugin in debug mode, but
the document is not getting validated with the xsd.
What is wrong in the above method as,
ValidationMessage[] messages = report.getValidationMessages(); is giving zero messages, even though the there are errors in the main document file.

I also had a lot of trouble trying to make org.eclipse.wst.sse.ui.sourcevalidation extension point work. I ended up using another extension point org.eclipse.wst.validation.validatorV2. The only difference between the 2 validators is that this one is only triggered when you save a file, not while you are typing. See an example bellow :
<extension id="customValidator" name="Custom Validator" point="org.eclipse.wst.validation.validatorV2">
<validator class="aaa.bbb.CustomValidator" markerId="customMarker" version="3">
<include>
<rules>
<contentType id="customContentType" exactMatch="false"/>
</rules>
</include>
</validator>
</extension>
Your implementation of the validator should override org.eclipse.wst.validation.AbstractValidator.

Related

Cannot migration from old 3.4.2 keycloak to latest version

I'm in charge of the migration of an old keycloak ( 3.4.2 ) to the latest version. I already migrated the database and the template.
The last thing that poses problem is custom providers for Account and Login.
I have two custom providers that extends :
FreeMarkerAccountProviderFactory
FreeMarkerLoginProviderFactory
At first, no providers was loaded at the starting of keycloak in version > 4.x. I investigate, and i found that override the default getId() method to return a value other than the default "freemarker" makes keycloak load them again.
But after that if i try to access the login page, i got a nullpointer exception on org.keycloak.services.resources.account.AccountFormService.init(AccountFormService.java:139)
Any idea ?
Edit : spi in provider are declared in META-INF/services and provider in standalone.xml
Edit 2 : I share the loginFormProvider as it as the same problem, trigger the same error but it less complicated in it's implementation
public class KeycloakFreeMarkerLoginFormsProvider extends FreeMarkerLoginFormProvider {
public KeycloakFreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
super(sesssion, freeMarker);
}
public Response createResponse(LoginFormsPages page) {
List<Foo> foo = // loading foo entities
List<Bar> bar = // loading bar entities
super.attributes.put("foo", foo);
super.attributes.put("bar", bar);
return super.createResponse(page);
}
}
public class KeycloakFreeMarkerLoginProviderFactory extends FreeMarkerLoginFormsProviderFactory {
private FreeMarkerUtil freeMarker;
public KeycloakFreeMarkerLoginProviderFactory() {
super();
}
#Override
public LoginFormsProvider create(KeycloakSession session) {
return new KeycloakFreeMarkerLoginFormsProvider(session, this.freeMarker);
}
#Override
public void init(Config.Scope config) {
this.freeMarker = new FreeMarkerUtil();
}
#Override
public void close() {
this.freeMarker = null;
}
/* Without getId() or with a value at freeMarker, the provider
is not load. With other value, get NPE */
#Override
public String getId() {
return "custom.provider";
}
}
Based on the comments chain, it appears that the problem is that the provider is not getting picked up by Keycloak. You have a couple of options for bundling a custom provider with Keycloak: as a module, or as a deployed war/ear/jar in the deployments directory.
Here's how to do it as a module:
You'll need to add some configuration (module.xml), and your jar, to the modules directory structure. It should look like something like this:
(keycloak root)
|- modules
|- system
|- layers
|- keycloak
|- com
|- yourcompany
|- yourmodule
|- main
|- your-module-name.jar
|- module.xml (see below)
Your module.xml should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<module name="com.yourcompany.yourmodule" xmlns="urn:jboss:module:1.6">
<resources>
<resource-root path="your-module-name.jar"/>
</resources>
<dependencies>
<!-- whatever module dependencies you need go here -->
<!-- these are just an example; you may or may not need them -->
<module name="org.jboss.logging" />
<module name="org.keycloak.keycloak-core"/>
<module name="org.keycloak.keycloak-services"/>
<module name="org.keycloak.keycloak-server-spi"/>
<module name="org.keycloak.keycloak-server-spi-private"/>
</dependencies>
</module>
Additionally, you'll need to configure standalone.xml and/or possibly standalone-ha.xml depending on your scenario (The default Keycloak Docker image uses -ha.xml by default). The pertinent section should look something like this:
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<web-context>auth</web-context>
<providers>
<provider>
classpath:${jboss.home.dir}/providers/*
</provider>
<!-- add this -->
<provider>
module:com.yourcompany.yourmodule
</provider>
<!-- end add -->
</providers>
<master-realm-name>master</master-realm-name>
<scheduled-task-interval>900</scheduled-task-interval>
...
</subsystem>
Lastly, like you mention, you'll need the correct config in your META-INF/services directory: a file with the fully qualified classname of the ProviderFactory as defined by the SPI, with one line containing the fully qualified classname of your implementation. In your case, the file should be called org.keycloak.forms.login.LoginFormsProviderFactory and its value should be one line: (com.yourpackage).KeycloakFreeMarkerLoginProviderFactory
If it's picked up, you should be able to see it listed in the providers config in the admin UI. To view, log in to the admin console, click on your username in the upper right, and select "Server Info", then click on the "Providers" tab. You should see your provider listed under "login".

Apache cxf jax-rs implementation with xml databind

I configured my rest service to implement content negotiation through Variant.
On jersey all works fine but on apache cxf something goes wrong.
No message body writer has been found for class ContentType: application/xml
It seems thath when I construct the response as xml type it cannnot find the correct body writer.
I configured jax-rs with jacksonJaxbJsonProvider and all works great with json databind.
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" />
</jaxrs:providers>
cxf-rt-frontend-jaxrs version 3.0.3
jackson-databind: 2.4.2
Any idea?
Add a #XmlRootElement(name="order") generated xml cannot be <orderId>data<orderId>, it should have root element. Thus updated code would look like
#XmlRootElement(name="order")
#XmlType(propOrder = { "orderId"})
public class OrderForConfirmationEmail implements Serializable {
#XmlElement
public long getOrderId() {
long orderId = new Random().nextLong();
return orderId;
}
}
Generated xml is
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><order xmlns="http://com.kp.swasthik/so/schema">
<orderId>369317779145370211</orderId>
</order>
and json is
{"orderId":6812414735706519327}

How to execute a jar file on jboss7 startup?

I have a simple java class which displays "waiting" text on execution , in "TMSCore" java project.
package com.stock.bo;
public class example {
/**
* #param args
*/
public static void main(String[] args) {
// ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("================================> waiting");
}
}
I have created TMSCore.jar and have set this example.class as entry point ,of my jar file.
Then i have created a module for this project in C:\Jboss\jboss-as-7.1.1\modules\org\tms\main , and pasted the jar in the same path
then i have created module.xml and pasted in the same path
module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.tms">
<resources>
<resource-root path="TMSCore.jar"/>
</resources>
</module>
then i have created a jboss-deployment-structure.xml in my webproject/web-inf directory
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.tms"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
when i start the server with my war containing above jboss-deployment-structure.xml, in my console its showing deployed TMSCore.jar
but my "waiting" text in my jar is not displayed on console
my requirement is i should get "================================> waiting" on my console once jboss is started up
or else can any one can suggest how to make a jar to execute on starting jboss server?
BTW i am using JBOSS7.1
If I am right it's because JBoss doesn't execute a library, it only loads the classes contained in the jar file. So putting a main function and generating an executable jar will not help.
If your goal is to have an global module on the server, I suggest you these modifications:
Create the module (as you have already done)
Declare it as dependency in jboss-deployment-structure.xml (as you have already done)
Declare it as global module on the server, so it will be loaded only once by JBoss. Edit the configuration file standalone.xml and modify the section:
<subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.tms" />
</global-modules>
</subsystem>
Now you have a module that have classes loaded only once. I you need to have only one instance of your Example class, the I suggest you to use an singleton:
public class Example {
// The only one instance
private static Example instance;
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
if(instance == null)
{
instance = new Example();
}
return instance;
}
}
Then to use it in all projects on the server
Example ex = Example.getInstance();
will give you back the existing instance (or create one the first time).
Notice: I can't try, so no guarantee that that will work.
Edit: Maybe a small modification of the Example class can also make it run during the classes loading:
public class Example {
// The only one instance
private static Example instance = new Example();
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
return instance;
}
}
Again: not tested.
You can't run a jar, but you can execute a startup method in a singleton.
#Startup
#Singleton
public class FooBean {
#PostConstruct
void atStartup() { ... }
#PreDestroy
void atShutdown() { ... }
}
This will happen at application start up and shutdown. I'd call the function you need from there.
See http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html

NServiceBus allows control over deserialization?

I am trying to integrate a legacy application with NServiceBus by wrapping XML exports from the application with a NServiceBus "wrapper" which basically strips out namespaces and adds the envelope and NSB namespace.
I have the basic solution working but only if the root element of the XML export exactly matches the NServiceBus message type name.
For example if the xml is:
<?xml version="1.0"?>
<Messages xmlns="http://tempuri.net/MyMessagesNamespace">
<!-- Note: the "V1" -->
<PolicyEndorsedV1>
...
</PolicyEndorsedV1>
</Messages>
then my handler code can happily deserialize:
namespace MyMessagesNamespace
{
public class PolicyEndorsedV1Handler : IHandleMessages<PolicyEndorsedV1>
{
public void Handle(PolicyEndorsedV1 message)
{
// All work fine!
...
}
}
}
However, if the export XML is
<?xml version="1.0"?>
<Messages xmlns="http://tempuri.net/MyMessagesNamespace">
<!-- Note: the "V1" has been removed -->
<PolicyEndorsed>
...
</PolicyEndorsed>
</Messages>
this will not be deserialised. NServiceBus tells me System.TypeLoadException: Could not handle type 'Beazley.Messages.Risks.Events.PolicyEndorsed', which is understandable as the only information it's got to go on is the name of the root node on the incoming xml.
I have tried to control the deserialization behaviour by adding some of the .Net Serialization attributes to my message definition:
[XmlRoot(ElementName = "PolicyEndorsed", Namespace = "", IsNullable = false)]
public partial class PolicyEndorsedV1
{
...
}
but this is ignored because NServiceBus uses it's own serializer (called XmlMessageSerializer) and not .Net's own XmlSerializer.
So does anyone know how I can do this? I think it would be nice to have the option to decouple the Xml names with their NSB messaging counterparts.
Many thanks
Does PolicyEndorsedV1 inherit from PolicyEndorsed?
If so, use IHandleMessages<PolicyEndorsed>, and PolicyEndorsedV1Handler will handle both types of objects.
For example:
public class PolicyEndorsedV1Handler : IHandleMessages<PolicyEndorsed>
{
public void Handle(PolicyEndorsed message)
{
// Handles both PolicyEndorsed and PolicyEndorsedV1 messages
}
}

JBossCache eviction listener

I am new on JBossCache. Reading the user documentation it says that a listener could be added to the Eviction class used, but I wasn't able to found how to do add one to the configuration file, or how that should be added.
I have tried to add an #CacheListener with a method #NodeEvicted, but that method
#CacheListener
public class EvictionListener {
#NodeEvicted
public void nodeEvicted(NodeEvent ne) {
System.out.println("Se borro el nodo");
}
}
and add it to the cache instance
CacheFactory factory = new DefaultCacheFactory();
this.cache = factory.createCache();
EvictionListener listener = new EvictionListener();
this.cache.create();
this.cache.addCacheListener(listener);
but the sysout isn't executed. For testing it, I am just running a simple Main value.
This is the configuration value I am using:
<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:jboss:jbosscache-core:config:3.2">
<transaction transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"/>
<eviction wakeUpInterval="20">
<default algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" wakeUpInterval="20">
<property name="maxNodes" value="20" />
</default>
</eviction>
</jbosscache>
The problem was solved because I wasn't reading the XML configuration file.
I was missing:
factory.createCache(file);