I have a properties file and I want to pass all key and values to a command, how can I do that?
say the property file looks file
size=small
perf=true
and the ant task looks like
<exec executable="${prog}" failonerror="true">
<!-- I want to add all properties from file as argument here, -->
</exec>
so that at runtime, the behavior isidentical to
<exec executable="${prog}" failonerror="true">
<arg value = "size"/>
<arg value = "small"/>
<arg value = "perf"/>
<arg value = "true"/>
</exec>
how can I do that?
Thanks
EDIT:
following Vadzim's suggestion, I am using script now.
<property file="test.properties" prefix="testproperty"/>
<target name = "test1">
<script language="javascript"> <![CDATA[
properties = project.getUserProperties()
echo = project.createTask( "echo" );
anotation = project.getProperty("testproperty.size")
echo.setMessage(anotation);
echo.perform();
for(key in properties) {
echo.setMessage(key);
echo.perform();
echo.setMessage(properties[key]);
echo.perform();
}
]]> </script>
</target>
However, getProperty() is working, but getProperties contains only java functions like notify()
$ant test1
test1:
[echo] small
[echo] notifyAll
[echo] function notifyAll() {/*
[echo] void notifyAll()
[echo] */}
[echo] values
[echo] function values() {/*
[echo] java.util.Collection values()
[echo] */}
[echo] containsKey
[echo] function containsKey() {/*
[echo] boolean containsKey(java.lang.Object)
[echo] */}
[echo] entrySet
[echo] function entrySet() {/*
[echo] java.util.Set entrySet()
[echo] */}
[echo] keySet
[echo] function keySet() {/*
[echo] java.util.Set keySet()
[echo] */}
[echo] put
[echo] function put() {/*
[echo] java.lang.Object put(java.lang.Object,java.lang.Object)
[echo] */}
[echo] contains
[echo] function contains() {/*
[echo] boolean contains(java.lang.Object)
[echo] */}
[echo] empty
[echo] false
[echo] equals
[echo] function equals() {/*
[echo] boolean equals(java.lang.Object)
[echo] */}
[echo] notify
[echo] function notify() {/*
[echo] void notify()
[echo] */}
[echo] class
[echo] class java.util.Hashtable
[echo] elements
[echo] function elements() {/*
[echo] java.util.Enumeration elements()
[echo] */}
[echo] keys
[echo] function keys() {/*
[echo] java.util.Enumeration keys()
[echo] */}
[echo] isEmpty
[echo] function isEmpty() {/*
[echo] boolean isEmpty()
[echo] */}
[echo] size
[echo] function size() {/*
[echo] int size()
[echo] */}
[echo] putAll
[echo] function putAll() {/*
[echo] void putAll(java.util.Map)
[echo] */}
[echo] clear
[echo] function clear() {/*
[echo] void clear()
[echo] */}
[echo] wait
[echo] function wait() {/*
[echo] void wait()
[echo] void wait(long)
[echo] void wait(long,int)
[echo] */}
[echo] containsValue
[echo] function containsValue() {/*
[echo] boolean containsValue(java.lang.Object)
[echo] */}
[echo] toString
[echo] function toString() {/*
[echo] java.lang.String toString()
[echo] */}
[echo] hashCode
[echo] function hashCode() {/*
[echo] int hashCode()
[echo] */}
[echo] clone
[echo] function clone() {/*
[echo] java.lang.Object clone()
[echo] */}
[echo] get
[echo] function get() {/*
[echo] java.lang.Object get(java.lang.Object)
[echo] */}
[echo] getClass
[echo] function getClass() {/*
[echo] java.lang.Class getClass()
[echo] */}
[echo] remove
[echo] function remove() {/*
[echo] java.lang.Object remove(java.lang.Object)
[echo] */}
BUILD SUCCESSFUL
Total time: 0 seconds
What's the correct way to iterate getProperties()'s result?
Any suggestions are greatly appreicated
EDIT2:
jbeard4 has an excellent explanation here. about the javascript issue.
so the correct way would be
<script language="javascript"> <![CDATA[
properties = project.getUserProperties()
var keyIter = properties.keySet().iterator();
while(keyIter.hasNext()) {
var key = keyIter.next();
var value = properties.get(key);
echo.setMessage(key+value);
echo.perform();
}
]]> </script>
I think this can be achieved only with custom script code.
See for example Is it possible to call ant task from a javascript scriptdef task?.
Just iterate over project.getProperties() and add exec args through API.
Related
I have a txt file with just one column: ids and the ids are separated by new line.
I want to read this file with a reader, but I think that I shouldn't use DelimitedLineTokenizer because my file doesn't have multiple columns. Here is the code:
<bean id="idsReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="ids" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="IdsMapper" />
</property>
</bean>
</property>
<property name="resource" value="#{stepExecutionContext['fileResource']}" />
<property name="encoding" value="UTF-8" />
</bean>
public class IdsMapper implements FieldSetMapper<String> {
#Override
public String mapFieldSet(FieldSet fs) throws BindException {
if (fs == null) {
return null;
}
return fs.readString("ids");
}
and here is the exception I receive:
[jobTaskExecutor-15] ERROR Encountered an error executing step loadIds
Message: IdsMapper.mapFieldSet(Lorg/springframework/batch/item/file/transform/FieldSet;)Ljava/lang/String;
Line | Method
->> -1 | mapFieldSet in batch.model.IdsMapper
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 7 | mapFieldSet in batch.model.IdsMapper$$ET3XDpZ2
| -1 | mapFieldSet . . . . . . . . . in batch.model.IdsMapper$$DT3XDpZ2
| 43 | mapLine in org.springframework.batch.item.file.mapping.DefaultLineMapper
| 180 | doRead . . . . . . . . . . . . in org.springframework.batch.item.file.FlatFileItemReader
| 88 | read in org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader
You could use your own implementation of linemapper:
<bean id="idsReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="lineMapper">
<bean class="com.example.TextFileLineMapper"/>
</property>
<property name="resource" value="file:#{stepExecutionContext['resource']}"/>
<property name="encoding" value="UTF-8" />
</bean>
public class TextFileLineMapper implements LineMapper<TextFileDto> {
#Override
public TextFileDto mapLine(String line, int lineNumber) {
TextFileDto textFileDto = new TextFileDto();
textFileDto.setId(line);
return textFileDto;
}
}
public class TextFileDto {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
I have an entity class that refers to itself as the parent class.
#NodeEntity
public class Config {
#Id
#GeneratedValue
private Long id;
#Relationship(type = "OVERRIDES", direction="INCOMING")
private Config parentConfig;
#Properties(allowCast=true, prefix="properties", delimiter=".")
private Map<String, String> properties;
....
}
When I run the built-in findById() method in my java code, the "parentConfig" is always the same as the child object. I never see the other end of the relationship. What am I doing wrong?
this works as expected but depends on how you want to model your config.
Assuming you want to express "Child overwrites parent config", which I would model as
CREATE (c:Config {name: 'Parent'}) <- [:OVERRIDES] - (c2:Config {name: 'Child'})
This gives you:
Then you must model the association as outgoing from the child object like this:
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.Relationship;
public class Config {
#Id
#GeneratedValue
private Long id;
private String name;
#Relationship(type = "OVERRIDES", direction = Relationship.OUTGOING)
private Config parent;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Config getParent() {
return parent;
}
#Override public String toString() {
return "Config{" +
"name='" + name + '\'' +
'}';
}
}
Turning this into a full example:
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.stereotype.Component;
interface ConfigRepo extends Neo4jRepository<Config, Long> {
Optional<Config> findOneByName(String name);
}
#Component
class Example implements CommandLineRunner {
#Autowired
private ConfigRepo configRepo;
#Override
public void run(String... args) throws Exception {
configRepo.findOneByName("Parent").ifPresent(c -> {
System.out.println("Config " + c + " has parent " + c.getParent());
});
configRepo.findOneByName("Child").ifPresent(c -> {
System.out.println("Config " + c + " has parent " + c.getParent());
});
}
}
#SpringBootApplication
public class SorecassocApplication {
public static void main(String[] args) {
SpringApplication.run(SorecassocApplication.class, args);
}
}
Will return
2018-10-10 09:20:21.960 INFO 3832 --- [ main] o.n.o.drivers.bolt.request.BoltRequest : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)-[r_o1:`OVERRIDES`]->(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Parent}
Config Config{name='Parent'} has parent null
2018-10-10 09:20:21.984 INFO 3832 --- [ main] o.n.o.drivers.bolt.request.BoltRequest : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)-[r_o1:`OVERRIDES`]->(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Child}
Config Config{name='Child'} has parent Config{name='Parent'}
If you model the relationship as INCOMING from the perspective of the child, than you have to inverse the relation ship in the nodes. Otherwise the output is as:
2018-10-10 09:22:54.929 INFO 3837 --- [ main] o.n.o.drivers.bolt.request.BoltRequest : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)<-[r_o1:`OVERRIDES`]-(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Parent}
Config Config{name='Parent'} has parent Config{name='Child'}
2018-10-10 09:22:54.951 INFO 3837 --- [ main] o.n.o.drivers.bolt.request.BoltRequest : Request: MATCH (n:`Config`) WHERE n.`name` = { `name_0` } WITH n RETURN n,[ [ (n)<-[r_o1:`OVERRIDES`]-(c1:`Config`) | [ r_o1, c1 ] ] ], ID(n) with params {name_0=Child}
Config Config{name='Child'} has parent null
Here are my dependencies to turn the examples into a running application:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sorecassoc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sorecassoc</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Please let me know if this solves your problem.
I have a multi module maven project with follwing child module
Tracker
|--Tracker-core
|--Tracker-dao
| |---src/main/resource/spring-dao-config.xml
|
|--Tracker-services
| |---src/main/resource/spring-service-config.xml
|
|--Tracker-web
In Tracker-dao, I have a spring-context.xml in the resource package. this scans for the dao classes and includes other datasource configuration.
spring-dao-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="com.gits.tracker"></context:component-scan>
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:/database.properties" />
</bean>
<import resource="classpath:hibernate-config.xml" />
<!-- Declare a datasource that has pooling capabilities -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- An AnnotationSessionFactoryBean for loading Hibernate mappings from
annotated domain classes. -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.gits.tracker.core.entity.Address</value>
<value>com.gits.tracker.core.entity.Company</value>
<value>com.gits.tracker.core.entity.Customer</value>
<value>com.gits.tracker.core.entity.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- <prop key="hibernate.query.factory_class">org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory</prop> -->
</props>
</property>
</bean>
</beans>
Junit test for the dao layer alone is working perfectly alright.
In the Tracker-service, I have used this Tracker-core as a dependency.
While running the Junit in Tracker-service, it goes error, saying failed to load Application context, failed to find atleast 1 bean matching the name.
spring-service-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- <import resource="classpath:spring-dao-config.xml"/> -->
<context:component-scan base-package="com.gits.tracker.service.services"></context:component-scan>
</beans>
Junit in Tracker-service
Problem is here:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:spring-service-config.xml" })
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:spring-service-config.xml" })
public class TestUserService extends
AbstractTransactionalJUnit4SpringContextTests {
private static Logger logger;
private static ApplicationContext ctx;
private UserService userService;
#BeforeClass
public static void init() {
logger = Logger.getLogger(User.class);
if (logger.isDebugEnabled()) {
logger.debug("IN DEBUG MODE");
}
}
#Before
public void localInit() {
logger.info("*************EXECUTING LOCALINIT*************");
ctx = new FileSystemXmlApplicationContext(
"src/main/resources/spring-config.xml");
userService = (UserService) ctx.getBean("userServiceImpl");
// userDao.executeQuery("delete from User where id<>3");
logger.info("*************DELETED ALL COMPANY FROM TABLE*************");
logger.info("*************EXITING OUT OF LOCALINIT*************");
}
#AfterClass
public static void stop() {
logger.debug("TEST COMPLETED");
}
private UserServiceImpl loadUserService() {
return (UserServiceImpl) ctx.getBean("userServiceImpl");
}
private UserDTO createTestUserDTO() {
UserDTO dto = new UserDTO("manoj", "manojpass", "true");
return dto;
}
#Test
public void testCreateUser() {
loadUserService();
UserDTO dto = createTestUserDTO();
Long id = userService.createUser(dto);
dto.setId(id);
UserDTO dto_1 = userService.getUserById(id);
org.junit.Assert.assertEquals(dto.toString(), dto_1.toString());
}
#Test
public void findByCriteriaWithAlias() {
loadUserService();
UserDTO dto = createTestUserDTO();
Long id = userService.createUser(dto);
CriteriaWithAlias criteriaWithAlias = new CriteriaWithAlias();
HashMap<String, String> alias = new HashMap<String, String>();
List<Criterion> criterions = new ArrayList<Criterion>();
Criterion criterion0 = Restrictions.eq("username", dto.getUsername());
criterions.add(criterion0);
criteriaWithAlias.setAlias(alias);
criteriaWithAlias.setCriterions(criterions);
List<UserDTO> users = userService
.findByCriteriaWithAlias(criteriaWithAlias);
for (UserDTO user : users) {
org.junit.Assert.assertFalse(user.getPassword().isEmpty());
org.junit.Assert.assertFalse(user.getId().toString().isEmpty());
org.junit.Assert.assertFalse(user.getUsername().isEmpty());
org.junit.Assert.assertFalse(user.getEnabled().isEmpty());
}
}
#Test
public void findByProjection() {
loadUserService();
UserDTO dto = createTestUserDTO();
userService.createUser(dto);
CriteriaWithAlias criteriaWithAlias = new CriteriaWithAlias();
HashMap<String, String> alias = new HashMap<String, String>();
HashMap<String, String> projections = new HashMap<String, String>();
List<Criterion> criterions = new ArrayList<Criterion>();
projections.put("username", "username");
projections.put("enabled", "enabled");
Criterion criterion0 = Restrictions.ne("username", "syed");
Criterion criterion1 = Restrictions.eq("enabled", "true");
criterions.add(criterion0);
criterions.add(criterion1);
criteriaWithAlias.setAlias(alias);
criteriaWithAlias.setCriterions(criterions);
criteriaWithAlias.setProjections(projections);
List<UserDTO> users = userService
.findByCriterionWithProjection(criteriaWithAlias);
for (UserDTO user : users) {
org.junit.Assert.assertNull(user.getPassword());
org.junit.Assert.assertNull(user.getId());
org.junit.Assert.assertFalse(user.getUsername().isEmpty());
org.junit.Assert.assertFalse(user.getEnabled().isEmpty());
}
}
I also tried importing the spring-dao-config of tracker-core in spring-service-config of the tracker-service module. But, that time, it says, spring-dao-config.xml file not found.
Please let me know whats wrong and what I have missed and suggest a solution for this.
I have added the dependency for each module in their own POM.xml and not all together in parent POM.xml
I found solution to my own question. Correct me if I'm wrong.
Its not possible to perform a JUnit test by accessing a config file from another maven module. JUnit is meant for Unit testing only. and not the integration testing.
The dependent maven modules config file will not be available in the classpath for the actual maven module you want to test.
So, what I did was, copied the config file of the dependent maven modules into the classpath of the actual maven module which I need to test. This might not be the correct way of doing it. but, I'm able to perform the JUnit test successfully.
Other way to perform Junit test in such case is to use tools like MOCKITO : https://code.google.com/p/mockito/
PF 3.5.10, Mojarra 2.1.21, omnifaces 1.5
I have a JSF library (with css files only). This library is in a .jar file. The css will be included in xhtml with
<h:outputStylesheet library="mylib" name="css/mycss.css">.
In html it is rendered to the following: localhost:8080/cms/javax.faces.resource/css/mycss.css.jsf?ln=mylib
CSS file of primefaces is rendered to:
localhost:8080/cms/javax.faces.resource/primefaces.js.jsf?ln=primefaces&v=3.5.10
Notice the library version (&3.5.10) at the end. How can I do the same thing ? Should I write version in Manifest.mf. Or how can I use jsf-versioning in jar file?
That's unfortunately not possible. Library versioning is not supported for resources in JAR.
You've basically 2 options:
Do it the easy and ugly way, include server's startup time as query string. Given that you're using OmniFaces, you could use its builtin #{startup} managed bean referring a java.util.Date instance in application scope:
<h:outputStylesheet ... name="some.css?#{startup.time}" />
<h:outputScript ... name="some.js?#{startup.time}" />
Or perhaps you've the version already as some application variable.
<h:outputStylesheet ... name="some.css?v=#{app.version}" />
<h:outputScript ... name="some.js?v=#{app.version}" />
Update: Notwithstanding, this doesn't work for <h:outputStylesheet>. See also: https://github.com/javaserverfaces/mojarra/issues/3945 or https://github.com/javaee/javaserverfaces-spec/issues/1395
It works for <h:outputScript> though, which had a very simliar bug report which was implemented pretty soon https://github.com/javaserverfaces/mojarra/issues/1216
Do the same as PrimeFaces, create a custom ResourceHandler.
public class MyVersionResourceHandler extends ResourceHandlerWrapper {
private ResourceHandler wrapped;
public MyVersionResourceHandler(ResourceHandler wrapped) {
this.wrapped = wrapped;
}
#Override
public Resource createResource(String resourceName) {
return createResource(resourceName, null, null);
}
#Override
public Resource createResource(String resourceName, String libraryName) {
return createResource(resourceName, libraryName, null);
}
#Override
public Resource createResource(String resourceName, String libraryName, String contentType) {
final Resource resource = super.createResource(resourceName, libraryName, contentType);
if (resource == null) {
return null;
}
return new ResourceWrapper() {
#Override
public String getRequestPath() {
return super.getRequestPath() + "&v=1.0";
}
#Override // Necessary because this is missing in ResourceWrapper (will be fixed in JSF 2.2).
public String getResourceName() {
return resource.getResourceName();
}
#Override // Necessary because this is missing in ResourceWrapper (will be fixed in JSF 2.2).
public String getLibraryName() {
return resource.getLibraryName();
}
#Override // Necessary because this is missing in ResourceWrapper (will be fixed in JSF 2.2).
public String getContentType() {
return resource.getContentType();
}
#Override
public Resource getWrapped() {
return resource;
}
};
}
#Override
public ResourceHandler getWrapped() {
return wrapped;
}
}
Or if you happen to already use OmniFaces, it could be done simpler:
public class YourVersionResourceHandler extends DefaultResourceHandler {
public YourVersionResourceHandler(ResourceHandler wrapped) {
super(wrapped);
}
#Override
public Resource decorateResource(Resource resource) {
if (resource == null || !"mylib".equals(resource.getLibraryName())) {
return resource;
}
return new RemappedResource(resource, resource.getRequestPath() + "&v=1.0");
}
}
Either way, to get it to run, register it as <resource-handler> in /META-INF/faces-config.xml of the JAR.
<application>
<resource-handler>com.example.MyVersionResourceHandler</resource-handler>
</application>
You can also use your project version and append it as a version number for your resource files. This can be done using the maven-war-plugin. The maven-war-plugin will look at your pages during the build time and replace the defined properties.
The following example shows you how to configure the maven-war-plugin to filter your webapp resources in order to inject the custom property asset.version:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
...
<properties>
<asset.version>${project.version}</asset.version>
</properties>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>ico</nonFilteredFileExtension>
<nonFilteredFileExtension>jpg</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<webResource>
<directory>${basedir}/src/main/webapp</directory>
<filtering>true</filtering>
</webResource>
</webResources>
</configuration>
</plugin>
...
</plugins>
</build>
</project>
The asset.version property can then be used in your JSF file.
Here is an example tested with JSF 2.2:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html ...
xmlns:jsf="http://xmlns.jcp.org/jsf">
...
<script jsf:name="js/libs/pure/pure-min.css?v=${project.version}" />
The result (in my case) will be the following:
<script type="text/javascript" src="/context-path/javax.faces.resource/js/libs/pure/pure-min.css.xhtml?v=1.0.15-SNAPSHOT"></script>
#Balusc response said "well, not a bug, but oversight and spec fail". It seems like css resources deployed in libraries cannot be versioned with mojarra 2.2.14. Is it right? I tried to implement your solution with a custom ResourceHandler, but resource returned by getWrapped().createResource(resourceName, libraryName) always returns null. It seems like createResource() try to find the library's resources (like css/layout.css) with path /META-INF/resources/ but it lacks the version.
To workaround the problem i have overrided createResource method on a custom ResourceHandler which extends Omnifaces DefaultResourceHandler to add version prefix to the resourceName
#Override
public Resource createResource(String resourceName, String libraryName) {
if (libraryName != null && libraryName.equals(LIBRARY_NAME)) {
if (!resourceName.startsWith(version)) {
resourceName = version + "/"+resourceName;
}
}
return super.createResource(resourceName, libraryName);
}
With this workaround the generated link looks like
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/1_0_3/css/layout.css?ln=common&v=1_0_3"/>
for the outputStylesheet declaration
<h:outputStylesheet library="common" name="css/layout.css" />
I'm not sure this is the best workaround.
Here is my code:
xsdFile:
<complexType name="Player">
<sequence>
<element name="Login" type="string"></element>
<element name="Passwd" type="string"></element>
</sequence>
</complexType>
<element name="Player" type="tns:Player"></element>
Build.xml:
<exec executable="${javahome}/bin/xjc" >
<arg value="-extension" />
<arg value="-b" />
<arg value="binding.xml" />
<arg value="-d" />
<arg value="${sources}" />
<arg value="-p" />
<arg value="metier" />
<arg value="Player.xsd" />
</exec>
</target>
binding.xml:
<jxb:bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc" elementFormDefault="qualified" attributeFormDefault="unqualified"
version="2.1">
<jxb:globalBindings>
<xjc:simple />
<xjc:serializable/>
</jxb:globalBindings>
And finnaly:
JAXBContext context = JAXBContext.newInstance(Player.class,ObjectFactory.class);
Unmarshaller decodeur = context.createUnmarshaller();
i add "xjc:simple" in order to have #XMLRootElement, but an exception is raised: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.example.org/Player"
It didn't work correctly because i got this:#XmlRootElement(name = "Player", namespace = "http://www.example.org/Player")
Instead of just: #XmlRootElement(name = "Player")
How can i remove this "namespace" ?
Thanks
If your XML schema indicates that the corresponding XML documents should be namespace qualified, then JAXB will generate a Java model with the expected namespace qualification. Below I'll describe a way in which you could leverage a StAX parser to fool JAXB into thinking it is parsing a namespace qualfied document:
Player
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="Player", namespace="http://www.example.org/Player")
public class Player {
private String login;
private String passwd;
#XmlElement(name="Login", namespace="http://www.example.org/Player")
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
#XmlElement(name="Passwd", namespace="http://www.example.org/Player")
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
NamespaceDelegate
We will create an implementation of StreamReaderDelegate. This delegate will report the namespace for all element events to be "http://www.example.org/Player". Note: This trick assumes that all your elements are qualified with the same namespace URI.
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class NamespaceDelegate extends StreamReaderDelegate {
private static String NAMESPACE = "http://www.example.org/Player";
public NamespaceDelegate(XMLStreamReader xsr) {
super(xsr);
}
#Override
public String getNamespaceURI() {
return NAMESPACE;
}
}
Demo
import java.io.FileInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Player.class);
FileInputStream xmlStream = new FileInputStream("input.xml");
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(xmlStream);
StreamReaderDelegate srd = new NamespaceDelegate(xsr);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Player player = (Player) unmarshaller.unmarshal(srd);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(player, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<Player>
<Login>FOO</Login>
<Passwd>BAR</Passwd>
</Player>
I just delete "ObjectFactory.class" and it works.
New code:
JAXBContext context = JAXBContext.newInstance(Player.class);
Unmarshaller decodeur = context.createUnmarshaller();