I have the following code which must add new values to the existing properties in the .properties file of, if the property doesn't exist - create it.
public String saveProperties(ArrayList<Property> properties, String customerId){
final String userPropFieldName = "users." + customerId + ".rules";
try{
PropertiesConfiguration props = new PropertiesConfiguration("/home/mikhail/bzrrep/DLP/DLPServer/src/main/resources/rules.properties");
for (Property property: properties){
String fieldName = "rules." + property.getName() + "." + property.getType();
String[] values = (property.getValue()).split("\\,");
for (String word: values){
System.out.print(word + " ");
}
if (util.exist(fieldName, props)){
props.setProperty(fieldName, values);
} else {
props.addProperty(fieldName, values);
}
String[] userProperties = props.getStringArray(userPropFieldName);
if (property.getAccepted()){
userProperties = util.addNewValue(userProperties, fieldName);
} else {
userProperties = util.removeValue(userProperties, fieldName);
}
props.setProperty(userPropFieldName, userProperties);
}
}catch (ConfigurationException e){
e.printStackTrace();
}
return "Saved";
}
I run it with the debugger and all values right, I mean, there are the proper name of the property and the proper values in the array, so, seen that it came up to the adding or setting new value, but finally I didn't see any changes in the property file.
Save your modified properties to file
props.save();
Read more: http://commons.apache.org/proper/commons-configuration/userguide/howto_properties.html#Saving
BTW, Saving properties directly to source code (src/main/resources/rules.properties) is usually bad idea.
Related
I have spring boot application where the user sends parameter and based on this parameter, there are configuration should be get.
I created file name configuration type “Configration_Types.properies” , now how can I read the configuration based on parameter pass I don't want to create database to lookup it?
Type1=Type1
Type1.width=60
Type1.heght=715
Type2=Type2
Type2.width=100
Type2.heght=720
Type3=Type3
Type3.width=100
Type3.heght=700
Type4=Type4
Type4.width=450
Type4.heght=680
Type5=Type5
Type5.width=270
Type5.heght=750
for example pass type4 should get configuration
Type4
450
680
The function could be like that :
public void readPropertyByType(String type)
{
InputStream input = null;
try
{
Properties prop = new Properties();
// if your type is Type4, the typeKey will be Type4. for compare data
String typeKey = type + ".";
String filename = "config.properties";
input = new FileInputStream(filename);
prop.load(input);
String typeInformation = "";
Enumeration< ? > e = prop.propertyNames();
while (e.hasMoreElements())
{
String key = (String)e.nextElement();
if (key.indexOf(typeKey) > 0)
{
typeInformation = typeInformation + prop.getProperty(key);
}
}
System.out.println("The data of type " + type + "is :" + typeInformation);
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
But you make a better design for your property file.
In case the order of property file never change, you can stop the
function when you get all expected data, don't need to loop whole
file.
Hope it help.
---UPDATE---
The property file could be like that :
Option 1
Type4.width=450
Type4.heght=680
Type5.width=450
Type5.heght=680
Option 2
Type4=450, 680
Type5=450, 680
Depend on each option, you can break the while loop when you got the expected data.
If you can modified your property file Configration_Types.properies like:-
type[0].width=60
type[0].heght=715
type[1].width=100
type[1].heght=720
type[2].width=100
type[2].heght=700
type[3].width=450
type[3].heght=680
type[4].width=270
type[4].heght=750
And your class for consume property values from property file would be:-
#Component
#ConfigurationProperties("type") // prefix type, find type.* values
public class GlobalProperties {
private List<Type> type = new ArrayList<Type>();
//getters and setters
public static class Type
{
private int width;
private int heght;
// getter setter
}
And As based on user params you can access the value from arraylist.
hope this help:
So, I'm trying to load some values from a JSON file:
{
Float :
null
,
test :
"hello"
,
Int :
2
}
However, the method I have below isn't working at all and doesn't load the file contents. No errors are thrown other than NPEs when I try to use various methods that return values loaded from the file. Any idea what I'm doing wrong?
protected void load(String name, String path) throws FileAlreadyLoadedException{
if (get(name) == null){
final ThunderFile tf = new ThunderFile(name, path);
//files.add(tf);
try {
final JSONObject jobj = (JSONObject)new JSONParser().parse(new FileReader(path + File.separator + name + ".json"));
new Thread(){
public void run(){
Iterator<?> i = jobj.keySet().iterator();
while(i.hasNext()){
String key = (String) i.next();
Object value = jobj.get(key);
if (!key.equals("") && !value.equals("")){
tf.set(key, value);
}
}
files.add(tf);
System.out.println("[Thunderbolt 2] Loaded " + tf.getName() + ".json");
this.interrupt();
}
}.start();
} catch(IOException | ParseException e) {
e.printStackTrace();
}
}else{
throw new FileAlreadyLoadedException("The File " + name + ".json is already loaded!");
}
}
EDIT:
To clarify, no values are loaded, even if my file looked like this:
{"Double":2.0}
Your JSON contains Float: null so Object value = jobj.get(key); for key Float is null.
Therefore !value.equals("") throws NPE.
I am trying to read an Ontology using Jena. I have a file Pizza.owl in the correct directory shown in the code, but I still get an error that the file is not found.
public static void ReadOntology(){
OntModel onto = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null);
String inputFileName = "C:\\Users\\najib\\studies\\pizza.owl";
try {
Logger logger = Logger.getLogger(Operations.class);
PropertyConfigurator.configure("C://Users//najib//Downloads//apache-jena-2.12.0//jena-log4j.properties");
//create the reasoning model using the base
OntModel model = ModelFactory.createOntologyModel();
// use the FileManager to find the input file
InputStream in = FileManager.get().open(inputFileName);
if (in == null) {
throw new IllegalArgumentException("File: " + inputFileName + " not found");
}
model.read(in, "");
//to list classes
ExtendedIterator<OntClass> classes = model.listClasses();
while (classes.hasNext()) {
OntClass cls = (OntClass) classes.next();
System.out.println("Classes: " + cls.getLocalName());
for (ExtendedIterator<OntClass> i = cls.listSubClasses(true); i.hasNext();) {
OntClass c = (OntClass) i.next();
System.out.print(" " + c.getLocalName() + "\n");
} // end for
}
} catch (Exception e) {
System.out.println(e);
}
}
}
I get the following error: java.lang.IllegalArgumentException: File: C:\Users\najib\studies\pizza.owl not found
When I read the javadoc of FileManager, I see you have to prefix your file parameter with "file:"
So (without testing this answer) I suggest to try it with:
String inputFileName = "file:/C:/Users/najib/studies/pizza.owl";
i want to give specific name to the uploaded file in my destination folder.. this is my action file code.. here i want to give name like CPIC_1.jpg,CPIC_2.jpg,CPIC_3.jpg,CPIC_4.jpg etc but every time it is assigning name : CPIC_1.jpg.. so how i declare variable ext so that through out it will be distinct..
CommercialFileBean b = (CommercialFileBean) form;
FormFile f = b.getF();
String s = request.getParameter("action");
HttpSession session = request.getSession(false);
String n = (String) session.getAttribute("str");
String email = session.getAttribute("uname").toString();
String status = (String) session.getAttribute("status");
String type = request.getParameter("type");
String pid;
long ext=0;
int id;
if (s.equalsIgnoreCase("finish")) {
return mapping.findForward(next);
} else { /// first else
String a = getServlet().getServletContext().getRealPath("/");
File file = new File(a + "uploaded/CPIC_"+ ++ext+".jpg");
if (!file.exists()) {
FileOutputStream out = new FileOutputStream(file);
out.write(f.getFileData());
out.close();
}
try {
if (n.equalsIgnoreCase("rent")) {
Session sess = UtilClass.createSession();
Transaction tx = sess.beginTransaction();
if (status.equalsIgnoreCase("new")) {
String sql1 = "select MAX(id) from Rentcommercialrecord where loginid=:email";
Query q1 = sess.createQuery(sql1);
q1.setParameter("email", email);
// JOptionPane.showMessageDialog(null, "max id is :");
List<Rentcommercialrecord> l = q1.list();
Rentcommercialrecord rc = l.get(l.size()-1);
id = rc.getId();
} else {
pid = (String) session.getAttribute("id");
id = Integer.parseInt(pid);
}
JOptionPane.showMessageDialog(null, " latest id is :" + id);
if (type.equalsIgnoreCase("frontpic")) {
try {
String file1 = f.getFileName();
JOptionPane.showMessageDialog(null, "file name is : "+file1);
Rentcommercialrecord rc1 = (Rentcommercialrecord) sess.get(Rentcommercialrecord.class, id);
rc1.setImg1("CPIC_" +ext+".jpg");
sess.update(rc1);
// JOptionPane.showMessageDialog(null, "img1");
} // img1 try ends
catch (Exception e) {
JOptionPane.showMessageDialog(null, "Second error is : " + e.getMessage());
}
} // fontpic if ends
else {
try {
String file1 = f.getFileName();
JOptionPane.showMessageDialog(null, "file name is : "+file1);
Rentcommercialrecord rc1 = (Rentcommercialrecord) sess.get(Rentcommercialrecord.class, id);
rc1.setImg2("CPIC_" +ext+".jpg");
sess.update(rc1);
// JOptionPane.showMessageDialog(null, "img2");
} // img2 try ends
catch (Exception e) {
JOptionPane.showMessageDialog(null, "Second error is : " + e.getMessage());
}
} // else img2 ends
// l.size if ends
tx.commit();
}
Make your variable ext as static.
static long ext = 0;
This will make the variable common to all instances.
Note : You need to store this value somewhere in db / file during restart and get it during application startup to make it consistent irrespective of restart of your application
You can make your ext variable static
Note: The scope of your static variable is for the current class Loader. ie, if it is a diff class loader is used , this will change.
other option is store the ext value in session and every time you upload a new image file, get this value from session and use it. And you need to put the new value back into session as well. This approach will work for per user. ie if your application is having diff users, for diff users it will have diff value based on session
You can use a static variable, but it won't be consistent through application restarts.
I would change approach and would read filenames, then extracting the numbers from their names, getting the highest, incrementing it and then writing a new file.
Use Apache Commons to avoid reinventing the wheel.
Kickoff example:
String path = getServlet().getServletContext().getRealPath("/") + "uploaded/";
String partialName = "CPIC_";
int markerLength = partialName.length();
int maxValue = 0;
// Find all files, if any, with name starting with "CPIC_" in the desired folder
List<File> files = FileUtils.listFiles(new File(path),
new PrefixFileFilter(partialName),
null);
if (!files.isEmpty()){
for (File file : files) {
// Strip marker and extension
int num = Integer.parseInt(
file.getName().substring(markerLength,
file.getName().indexOf("."))
);
// compare the number, if greater, set as new max value
if (num > maxValue) {
maxValue = num;
}
}
}
String newFile = partialName + ++maxValue + ".jpg";
System.out.println("Next file name would be : " + newFile);
I have a Java Properties object that I load from an in-memory String, that was previously loaded into memory from the actual .properties file like this:
this.propertyFilesCache.put(file, FileUtils.fileToString(propFile));
The util fileToString actually reads in the text from the file and the rest of the code stores it in a HashMap called propertyFilesCache. Later, I read the file text from the HashMap as a String and reload it into a Java Properties object like so:
String propFileStr = this.propertyFilesCache.get(fileName);
Properties tempProps = new Properties();
try {
tempProps.load(new ByteArrayInputStream(propFileStr.getBytes()));
} catch (Exception e) {
log.debug(e.getMessage());
}
tempProps.setProperty(prop, propVal);
At this point, I've replaced my property in my in-memory property file and I want to get the text from the Properties object as if I was reading a File object like I did up above. Is there a simple way to do this or am I going to have to iterate over the properties and create the String manually?
public static String getPropertyAsString(Properties prop) {
StringWriter writer = new StringWriter();
prop.list(new PrintWriter(writer));
return writer.getBuffer().toString();
}
There seems to be a problem with #Isiu answer. After that code Properties are truncated, like there is some limit to string length. Proper way is to use code like this:
public static String getPropertyAsString(Properties prop) {
StringWriter writer = new StringWriter();
try {
prop.store(writer, "");
} catch (IOException e) {
...
}
return writer.getBuffer().toString();
}
It's not directly related to your question but if you just want to print out properties for debugging you can do something like this
properties.list(System.out);
If you are using Java 8 or above, here is a single statement solution with the possibility to control the format by yourself:
String properties = System.getProperties().entrySet()
.stream()
.map(e -> e.getKey() + ":" + e.getValue())
.collect(Collectors.joining(", "));
I don't completely understand what you're trying to do, but you can use the Properties class' store(OutputStream out, String comments) method. From the javadoc:
public void store(OutputStream out,
String comments)
throws IOException
Writes this property list (key and element pairs) in this Properties table to the output stream in a format suitable for loading into a Properties table using the load(InputStream) method.
You can do as below also:
Properties p = System.getProperties();
Enumeration keys = p.keys();
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
String value = (String)p.get(key);
System.out.println(key + ": " + value);
}
Another function to print all the values of a field is :
public static <T>void printFieldValue(T obj)
{
System.out.printf("###" + obj.getClass().getName() + "###");
for (java.lang.reflect.Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
String name = field.getName();
Object value = null;
try{
value = field.get(obj);
}catch(Throwable e){}
System.out.printf("#Field name: %s\t=> %s%n", name, value);
}
}
Using the list method is incorrect because it should be used only for debugging purposes
Prints this property list out to the specified output stream.
This method is useful for debugging.
It doesn't escape keys which contains special characters, like = or :.
The store method should be used, but it inserts a comment and timestamp. The following code removes these additional lines and returns a text with normalized new lines.
Java
public static String propertiesToString(Properties properties) throws IOException {
if (properties == null) {
return null;
}
if (properties.isEmpty()) {
return "";
}
StringWriter writer = new StringWriter();
properties.store(writer, null);
String text = normalizeNewLines(writer.toString());
List<String> lines = new ArrayList<>(Arrays.asList(text.split("\n")));
lines.remove(0);
return lines.stream().collect(Collectors.joining("\n"));
}
private static String normalizeNewLines(String text) {
return text.replace("\r\n", "\n").replace("\r", "\n");
}
Groovy
static String propertiesToString(Properties properties) {
if (properties.is(null)) {
return null
}
if (properties.isEmpty()) {
return ''
}
def writer = new StringWriter()
properties.store(writer, null)
def lines = normalizeNewLines(writer).split('\n') as List
lines.remove(0)
return lines.join('\n')
}
private static String normalizeNewLines(String text) {
return text.replace('\r\n', '\n').replace('\r', '\n')
}