Apache Commons Configuration2 how to read data from InputStream - java

How can I read the data from InputStream by using Apache Commons Configuration2?
FileBasedConfigurationBuilder<XMLConfiguration> builder =
new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
.configure(
new Parameters()
.xml()
.setFileName("")
.setExpressionEngine(new XPathExpressionEngine())
);
XMLConfiguration config = builder.getConfiguration();
config.read(sourceJarFile.getInputStream(sourcePropertiesEntry))
Gives the above code, I will get the below exception if the setFileName is given empty string.
org.apache.commons.configuration2.ex.ConfigurationException: Could not locate: org.apache.commons.configuration2.io.FileLocator#61dc03ce[fileName=tmp.xml,basePath=<null>,sourceURL=,encoding=<null>,fileSystem=<null>,locationStrategy=<null>]
at org.apache.commons.configuration2.io.FileLocatorUtils.locateOrThrow(FileLocatorUtils.java:346)
at org.apache.commons.configuration2.io.FileHandler.load(FileHandler.java:972)
at org.apache.commons.configuration2.io.FileHandler.load(FileHandler.java:702)
at org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder.initFileHandler(FileBasedConfigurationBuilder.java:312)
at org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder.initResultInstance(FileBasedConfigurationBuilder.java:291)
at org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder.initResultInstance(FileBasedConfigurationBuilder.java:60)
at org.apache.commons.configuration2.builder.BasicConfigurationBuilder.createResult(BasicConfigurationBuilder.java:421)
at org.apache.commons.configuration2.builder.BasicConfigurationBuilder.getConfiguration(BasicConfigurationBuilder.java:285)
at com.test.installer.App.getXMLConfigurationProperties(App.java:185)
If I give null or just not call setFileName(); I will get the unable to load configuration exception at the read() line.
org.apache.commons.configuration2.ex.ConfigurationException: Unable to load the configuration
at org.apache.commons.configuration2.XMLConfiguration.load(XMLConfiguration.java:986)
at org.apache.commons.configuration2.XMLConfiguration.read(XMLConfiguration.java:954)
at com.test.installer.App.updateExistedProperties(App.java:84)

From the example in the API documentation:
Set up your file parameters (encoding and such):
FileBasedBuilderParameters fileparams = ...
FileBasedConfigurationBuilder<PropertiesConfiguration> builder =
new FileBasedConfigurationBuilder<>(PropertiesConfiguration.class).configure(fileparams);
and then:
FileBasedConfiguration config = builder.getConfiguration();
FileHandler fileHandler = new FileHandler(config);
Inputstream istream = ...
fileHandler.load(istream);
Note that you cannot use autosave with this. To save you'd probably need to provide an OutputStream. Something like:
fh.save(ostream)

Proper way of loading XML configuration data from Input Stream (in commons-collections 2.x) is as follows:
XMLConfiguration cfg = new BasicConfigurationBuilder<>(XMLConfiguration.class).configure(new Parameters().xml()).getConfiguration();
FileHandler fh = new FileHandler(cfg);
fh.load(inputStream);
After calling load() cfg will contain loaded configuration.
Also note, that using XMLConfiguration.read() method should not be used, as this method is designed for internal use and probably will be renamed to _read() in future (see: https://issues.apache.org/jira/browse/CONFIGURATION-641).

You can use XMLConfiguration.read(InputStream in) , but as far as I know, you need to have a XML file somewhere. The reason is that when you either get the configuration from the builder or call the read method above, there are a few checks in the private load method (line 963 in the XMLConfiguration.java in the source files).
Parameters params = new Parameters();
FileBasedConfigurationBuilder<XMLConfiguration> fileBuilder =
new FileBasedConfigurationBuilder<>(XMLConfiguration.class)
.configure(params.fileBased().setFileName("/tmp/dummy.xml"));`
XMLConfiguration xmlConfiguration = fileBuilder.getConfiguration();
xmlConfiguration.read(inputStream);
The dummy file can be anything as long as it’s well-formed, it doesn’t need to be valid. In my case, /tmp/dummy.xml just contains <_/>.

Related

How to pass property file from spring config server to YAML reader?

I am currently moving my property files to spring-config-server. I have created a config server and it is running on my localhost(http://localhost:8080).
In my application I can able to access the properties from config server for different environments like local and dev. But in my code I was reading one of the property file by Yaml reader for other mappings.
The following the code for reader:
Yaml yaml = new Yaml();
InputStream inputStream = clazz
.getClassLoader()
.getResourceAsStream("application-myprops.yml");
MyPropsYaml obj = yaml.loadAs(inputStream, MyPropsYaml.class);
By executing this I am getting the following error:
org.yaml.snakeyaml.error.YAMLException: java.io.IOException: Stream closed
at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:218)
at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:171)
at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:126)
at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1198)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:308)
at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:248)
at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:213)
at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:165)
at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:155)
at org.yaml.snakeyaml.composer.Composer.getSingleNode(Composer.java:141)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:151)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:491)
at org.yaml.snakeyaml.Yaml.loadAs(Yaml.java:484)
I have tried by passing the config server url as well like this, but it didn't work
Yaml yaml = new Yaml();
InputStream inputStream = clazz
.getClassLoader()
.getResourceAsStream("http://localhost:8080/application-myprops.yml");
MyPropsYaml obj = yaml.loadAs(inputStream, MyPropsYaml.class);
I dont want to place application-myprops.yml in my application. It should be in my config server. How can I make it work like that.
Thanks in advance!

Java: mock multipartfile in unit test

I am trying to mock a MultipartFile and I want to create the mock with a stream that I create in the test
I've tries with a file without much luck either. Here is what I have tried so far
FileInputStream stream = new
FileInputStream("MOCK_file.xlsm");
MultipartFile f1 = new MockMultipartFile("file1",stream);
MultipartFile[] files = {f1};
return files;
I get a fileNotFoundException. Where should I put my file in my Maven project so the unit tests can find the file?
-- OR --
How do I just create a stream in code without the use of a file?
Even better you can mock only the MultipartFile and you will not be needing the InputStream at all.
To do so you only need to do mock(MultiPartFile.class) and then define what each function will do
For example if you use the name
final MultipartFile mockFile = mock(MultipartFile.class);
when(mockFile.getOriginalFilename()).thenReturn("CoolName");
This way you wont have to bother with actual files neither unexpected responses as you will be defining them
How do I just create a stream in code without the use of a file?
You could use a ByteArrayInputStream to inject mock data. It's pretty straightforward for a small amount of data:
byte[] data = new byte[] {1, 2, 3, 4};
InputStream stream = new ByteArrayInputStream(data);
Otherwise, you need to figure out what directory is your code running from, which is something that depends on how it's being run. To help with that you could print the user.dir system property, which tells you the current directory:
System.out.println(System.getProperty("user.dir"));
Alternatively, you can use a full path, rather than a relative one to find the file.
Put the file in
src/test/resources/MOCK_file.xlsm
Read from JUnit class with:
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("MOCK_file.xlsm");

NoSuchFileException in Files.newInputStream with StandardOpenOption.CREATE

I am trying to open a file for reading or create the file if it was not there.
I use this code:
String location = "/test1/test2/test3/";
new File(location).mkdirs();
location += "fileName.properties";
Path confDir = Paths.get(location);
InputStream in = Files.newInputStream(confDir, StandardOpenOption.CREATE);
in.close();
And I get java.nio.file.NoSuchFileException
Considering that I am using StandardOpenOption.CREATE option, the file should be created if it is not there.
Any idea why I am getting this exception?
It seems that you want one of two quite separate things to happen:
If the file exists, read it; or
If the file does not exist, create it.
The two things are mutually exclusive but you seem to have confusingly merged them. If the file did not exist and you've just created it, there's no point in reading it. So keep the two things separate:
Path confDir = Paths.get("/test1/test2/test3");
Files.createDirectories(confDir);
Path confFile = confDir.resolve("filename.properties");
if (Files.exists(confFile))
try (InputStream in = Files.newInputStream(confFile)) {
// Use the InputStream...
}
else
Files.createFile(confFile);
Notice also that it's better to use "try-with-resources" instead of manually closing the InputStream.
Accordingly to the JavaDocs you should have used newOutputStream() method instead, and then you will create the file:
OutputStream out = Files.newOutputStream(confDir, StandardOpenOption.CREATE);
out.close();
JavaDocs:
// Opens a file, returning an input stream to read from the file.
static InputStream newInputStream(Path path, OpenOption... options)
// Opens or creates a file, returning an output stream that
// may be used to write bytes to the file.
static OutputStream newOutputStream(Path path, OpenOption... options)
The explanation is that OpenOption constants usage relies on wether you are going to use it within a write(output) stream or a read(input) stream. This explains why OpenOption.CREATE only works deliberatery with the OutputStream but not with InputStream.
NOTE: I agree with #EJP, you should take a look to Oracle's tutorials to create files properly.
I think you intended to create an OutputStream (for writing to) instead of an InputStream (which is for reading)
Another handy way of creating an empty file is using apache-commons FileUtils like this
FileUtils.touch(new File("/test1/test2/test3/fileName.properties"));

Hibernate can't read hibernate.cfg.xml

I'm using Hibernate 4.1 in GWT app running on Jetty 1.6
Got the next code to start up hib.instance:
Configuration configuration = new Configuration().configure(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
First line gives me an error:
org.hibernate.HibernateException: ...hibernate.cfg.xml not found
at org.hibernate.internal.util.ConfigHelper.getResourceAsStream(ConfigHelper.java:173)
But I checked hibernate.cfg.xml availability just before loading hib.config:
File conf = new File(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
System.out.println(conf.canRead());
Sysout returns true.
Looking into source of ConfigHelper.getResourceAsStream with break point in it:
InputStream stream = null;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader!=null) {
stream = classLoader.getResourceAsStream( stripped );
}
if ( stream == null ) {
stream = Environment.class.getResourceAsStream( resource );
}
if ( stream == null ) {
stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
}
if ( stream == null ) {
throw new HibernateException( resource + " not found" );
}
I'm doing something wrong (doesn't understand something) or it's really no xml loaders here?
There are several things wrong here.
First of all, this:
Configuration configuration = new Configuration().configure(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
does not do what you think it does.
Your example is not checking the availability of the configuration file. It is checking whether the file exists on the file system, not in the classpath. This difference is important.
Without knowing more about how you build and deploy your webapp or how you have your files organized, it's hard to give you any more concrete advice, other than try copying the "hibernate.cfg.xml" to the root of your classpath, and just passing that to the configure() method. That should work.
So your code should be:
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
And your hibernate.cfg.xml file should be in the root of your classpath.
Alternatively, if you're using Maven, just put it under the "resources" folder and Maven should do the rest for you.
This way custom-located config file is loaded:
File conf = new File(ABS_PATH_TO_CONFIG+File.separator+"hibernate.cfg.xml");
Configuration configuration = new Configuration().configure(conf.getAbsoluteFile());
FYC: configure() method are overloaded
I'll tell you that program won't never treat you.
about your problem, you can do like this to get the path of the config file:
String basePath = PropertiesUtil.class.getResource("/").getPath();
then read it
InputStream in = new FileInputStream(basePath + fileName);
Good luck!

how to do Serializtionf of a file

i have a xml file named as default xml with sample contents as
<check>hi</check>
in my application i am doing an operation such that it wil operate on the xml and writes the new value to it, by overriding the newvalue on the oldone
ex:
<check>hi updated</check>
and i closed my application now
my problem is here:
whenever i start application again i should get the contents of default xml as
<check>hi<check>
instead of
<check>hi updated</check>
how can i achieve this ,can i have an steps to implement this r any sample code to implement this
i wil b thankful to ur valuable replies
Um... don't overwrite the file then? Keep the changes in memory or work on a temporary copy.
Writing data:
FileOutputStream os = new FileOutputStream("C:/cust.xml");
XMLEncoder encoder = new XMLEncoder(os);
Person p = new Person();
p.setFirstName("John");
encoder.writeObject(p);
encoder.close();
Reading data:
FileInputStream os = new FileInputStream("C:/cust.xml");
XMLDecoder decoder = new XMLDecoder(os);
Person p = (Person)decoder.readObject();
decoder.close();
EDIT: You can also use XStream library. Here will you find a complete tutorial about it

Categories

Resources