2009-05-16 13 views
45

जावा गुण फ़ाइल संदर्भ अन्य गुण फ़ाइल कर सकते हैं?java.util.Properties में किसी अन्य संपत्ति का संदर्भ कैसे लें?

## define a default directory for Input files 
dir.default=/home/data/in/ 

dir.proj1=${dir.default}p1 
dir.proj2=${dir.default}p2 
dir.proj3=${dir.default}p3 

क्या यह संभव है?

+1

के लिए आप [अपाचे कॉमन्स विन्यास] (http: //commons.apache.org/configuration/)। – LaurentG

+0

क्या यह एक ही फाइल में अन्य गुणों को संदर्भित करने या अन्य फ़ाइलों में गुणों का संदर्भ देने के बारे में एक प्रश्न है? –

उत्तर

5

java.util.Properties क्लास आपके लिए यह नहीं करेगा। गुणों को उपclass करना बहुत मुश्किल नहीं होगा, लोड() विधि को ओवरराइड करें और प्रतिस्थापन स्वयं करें।

6

मानक गुण फ़ाइलें केवल कुंजी-मूल्य जोड़े हैं। टेक्स्ट प्रारूप में, Properties केवल कुंजी से मूल्य को अलग करता है और कुछ सरल चीजें करता है जैसे बच निकलने वाले वर्णों को अनुमति देना। आप वर्बोज़ एक्सएमएल सिंटैक्स में इकाइयों को परिभाषित करने में सक्षम हो सकते हैं।

यदि आप अपना खुद का प्रतिस्थापन वाक्यविन्यास चाहते हैं, तो आप किसी अन्य स्ट्रिंग के साथ एक लौटा मूल्य का उपयोग कर सकते हैं। वैकल्पिक रूप से, आप Properties का अपना संस्करण लिख सकते हैं या फ़ाइल उत्पन्न करते समय प्रतिस्थापन कर सकते हैं।

12

Eproperties is the open source project जो कुछ अन्य सुविधाओं के साथ परिवर्तनीय प्रतिस्थापन प्रदान करता है - हालांकि प्रतिस्थापन तर्कसंगत रूप से सबसे उपयोगी हो सकता है। यह java.util.Properties का उप-वर्ग है, और इसका उपयोग किसी भी अन्य वर्ग द्वारा किया जा सकता है जो गुणों के रूप में कॉन्फ़िगरेशन जानकारी ले सकता है।

+1

इंस्टॉल करने और उपयोग करने के लिए केवल एक जार, आपके क्लासपाथ में एपैश सामान्य लॉगिंग है। वाक्यविन्यास का एक सिंहावलोकन [यहां] (http://eproperties.googlecode.com/svn/docs/1.1.2/manual/index.html)। – Vladtn

49

यह वही है जो आप चाहते हैं, यह थोड़ा पुराना है, लेकिन आपकी आवश्यकताओं के लिए काम कर सकता है।

Enabling constant substitution in Property Values

आप संपत्ति के मूल्य में कहीं भी एक निरंतर स्थानापन्न कर सकते हैं, और यहां तक ​​कि, एक मूल्य के भीतर एक से अधिक स्थिर है निम्न उदाहरण में:

CONST_1 = shoes and ships 
CONST_2 = sealing wax 
SomeValue = {CONST_1} and {CONST_2} 

इस उदाहरण में, "SomeValue" संपत्ति "जूते और जहाजों और सीलिंग मोम" का मूल्यांकन करती है।

+2

हां, यह पुराना है, लेकिन यह काम करता है और निर्भरताओं के gobs में खींच नहीं है, या बहुत अधिक करने की कोशिश करो। –

+1

मेरे लिए यह काम नहीं कर रहा है .. क्या यह बहिष्कृत है या कुछ? : एस – ianaz

+2

@ianaz कृपया लिंक में ध्यान दें कि आपको गुणों के बजाय उप-वर्ग XProperties का उपयोग करना है। ऐसा इसलिए हो सकता है कि आप कुछ भी नहीं देखते हैं। –

1

इस विशेष मामले में (और others भी में), तो आप बेहतर परिभाषित करने विभिन्न गुणों से दोहराव को हल चाहते हैं:

  1. परिवर्तन: dir.proj1=dir.default /p1dir.proj1_extension=/p1 में
  2. आगे जोड़ते: dir.defaultdir.proj1_extension करने के लिए अपने आवेदन कोड में proj1 का पूरा स्थान प्राप्त करें।

अन्य परियोजनाओं के लिए भी ऐसा ही करें।

6

कॉमन्स कॉन्फ़िगर lib यह भी कर सकता है। http://commons.apache.org/configuration/userguide/overview.html#Using_Configuration

हालांकि, जैसा कि पहले से बताया गया है, ईप्रोपर्टीज लाइब्रेरी पर एक नज़र डालें; http://code.google.com/p/eproperties/

यह शामिल करने सहित कई स्वच्छ सुविधाओं (जैसे प्रतिस्थापन, घोंसले, सूचियों) का समर्थन करता है, जावा गुणों को बढ़ाता है और कॉमन्स कॉन्फ़िगर से थोड़ा हल्का वजन है (जो आपको सिंटैक्स समेत गुणों को शामिल करने की अनुमति देता है)।

3

eproperties के बाद से एक तरह से नहीं रखा जाता है और आम विन्यास प्रवेश करने पर निर्भरता (जो विडंबना यह है कि मतलब है कि आप लॉगिंग कॉन्फ़िगर करने के लिए इसका इस्तेमाल नहीं कर सकते हैं) मैं इस कोड का टुकड़ा है जो केवल commons-lang(3) की आवश्यकता है अंतर्वेशित गुण लोड करने के लिए का उपयोग किया है:

@SuppressWarnings("serial") 
public static Map<String,String> loadPropertiesMap(InputStream s) throws IOException { 
    final Map<String, String> ordered = new LinkedHashMap<String, String>(); 
    //Hack to use properties class to parse but our map for preserved order 
    Properties bp = new Properties() { 
     @Override 
     public synchronized Object put(Object key, Object value) { 
      ordered.put((String)key, (String)value); 
      return super.put(key, value); 
     } 
    }; 
    bp.load(s); 
    final Map<String,String> resolved = new LinkedHashMap<String, String>(ordered.size()); 
    StrSubstitutor sub = new StrSubstitutor(new StrLookup<String>() { 
     @Override 
     public String lookup(String key) { 
      String value = resolved.get(key); 
      if (value == null) 
       return System.getProperty(key); 
      return value; 
     } 
    }); 
    for (String k : ordered.keySet()) { 
     String value = sub.replace(ordered.get(k)); 
     resolved.put(k, value); 
    } 
    return resolved; 
} 

इनपुट:

blah=${user.dir} 
one=1 
two=2 
five=5 
fifteen=${one}${five} 
twoonefive=${two}${fifteen} 
six=6 

आउटपुट:

+०१२३५१६४१०६
blah=/current/working/dir 
one=1 
two=2 
five=5 
fifteen=15 
twoonefive=215 
six=6 

स्पष्ट रूप से आप Map<String,String> को Properties ऑब्जेक्ट में वापस कर सकते हैं यदि आपको इसकी आवश्यकता हो। मैं पहले घोषित गुणों और सिस्टम गुणों के आधार पर हल करता हूं लेकिन आप स्पष्ट रूप से StrSubstitutor.lookup में समायोजित कर सकते हैं।

0

नीचे गुणों को पढ़ने के लिए जावा में एक कोड स्निपेट है जो अन्य गुणों का संदर्भ देता है। विशेष रूप से, ये पुन: प्रयोज्य प्रश्न हैं लेकिन अन्य सामान भी हो सकते हैं।

LinkedHashMap<String, String> sqlsRaw = loadPropertiesFromFile(); 
LinkedHashMap<String, String> sqls = new LinkedHashMap<>(); 
StrSubstitutor substitutor = new StrSubstitutor(sqls); 

for (Map.Entry<String, String> entry : sqlsRaw.entrySet()) { 
    String sql = entry.getValue(); 
    try { 
     sql = substitutor.replace(sql); 
    } catch (Exception e) { 
     throw new RuntimeException("Found an sql with a non replaced reference to another. Please validate that the required key was defined before this sql: " + entry.getValue(), e); 
    } 
    sqls.put(entry.getKey(), sql); 
} 

उदाहरण गुण:

key1=value1 
key21=value2 ${key1} 

इस चलाने के बाद, key21 मूल्य value2 value1 होगा।

* अपाचे के StrSubstitutor का उपयोग करना।

+1

** SQL के लिए 'StrSubstitutor' का उपयोग न करें! ** यह SQL इंजेक्शन से सुरक्षित नहीं होगा। इसके अलावा मुझे यह बुरा नहीं लगता है और शायद आप इसे याद कर चुके हैं, लेकिन मैंने आपके पहले से 2 साल पहले StrSubstitutor का उपयोग करके एक उत्तर प्रदान किया है। –

+0

@AdamGent - यह कुंजी द्वारा प्रश्नों के संदर्भ के लिए तंत्र है - मान नहीं। सभी प्रश्न तैयार कथन हैं :) –

0

कॉन्फ़िगरेशन फ़ाइल प्रारूप key=value या key:value प्रारूप में बयान शामिल है। उनके संभावित तरीके हैं जहां एक महत्वपूर्ण मूल्य दूसरे कुंजी मान को संदर्भित कर सकता है। एक उद्घाटन "$ {" और "0" को एक कुंजी के रूप में व्याख्या किया गया है। प्रतिस्थापित चर का मान सिस्टम प्रॉपर्टी या कॉन्फ़िगरेशन फ़ाइल में ही परिभाषित किया जा सकता है।

क्योंकि Properties inherits Hashtable, से put और putAll तरीकों एक Properties object के लिए लागू किया जा सकता है।

Map<String, String> map = new LinkedHashMap<String, String>(); 
map.put("key", "vlaue"); 
Properties props = new Properties(); 
props.putAll(map); 

@Adam Gent की पोस्ट में विस्तृत व्याख्या। commons-text-1.1.jar

import org.apache.commons.text.StrLookup; 
import org.apache.commons.text.StrSubstitutor; 

public class Properties_With_ReferedKeys { 
    public static void main(String[] args) { 

     ClassLoader classLoader = Properties_With_ReferedKeys.class.getClassLoader(); 

     String propertiesFilename = "keys_ReferedKeys.properties"; 
     Properties props = getMappedProperties(classLoader, propertiesFilename); 

     System.out.println(props.getProperty("jdk")); 

    } 


    public static Properties getMappedProperties(ClassLoader classLoader, String configFilename) { 
     Properties fileProperties = new Properties(); 

     try { 
      InputStream resourceAsStream = classLoader.getResourceAsStream(configFilename); 

      Map<String, String> loadPropertiesMap = loadPropertiesMap(resourceAsStream); 
      Set<String> keySet = loadPropertiesMap.keySet(); 
      System.out.println("Provided 'Key':'Value' pairs are..."); 
      for (String key : keySet) { 
       System.out.println(key + " : " + loadPropertiesMap.get(key)); 
      } 

      fileProperties.putAll(loadPropertiesMap); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return fileProperties; 
    } 
    public static Map<String,String> loadPropertiesMap(InputStream inputStream) throws IOException { 
     final Map<String, String> unResolvedProps = new LinkedHashMap<String, String>(); 

     /*Reads a property list (key and element pairs) from the input byte stream. 
     * The input stream is in a simple line-oriented format. 
     */ 
     @SuppressWarnings("serial") 
     Properties props = new Properties() { 
      @Override 
      public synchronized Object put(Object key, Object value) { 
       unResolvedProps.put((String)key, (String)value); 
       return super.put(key, value); 
      } 
     }; 
     props.load(inputStream); 

     final Map<String,String> resolvedProps = new LinkedHashMap<String, String>(unResolvedProps.size()); 

     // Substitutes variables within a string by values. 
     StrSubstitutor sub = new StrSubstitutor(new StrLookup<String>() { 
      @Override 
      public String lookup(String key) { 

       /*The value of the key is first searched in the configuration file, 
       * and if not found there, it is then searched in the system properties.*/ 
       String value = resolvedProps.get(key); 

       if (value == null) 
        return System.getProperty(key); 

       return value; 
      } 
     }); 

     for (String key : unResolvedProps.keySet()) { 

      /*Replaces all the occurrences of variables with their matching values from the resolver using the given 
      * source string as a template. By using the default ${} the corresponding value replaces the ${variableName} sequence.*/ 
      String value = sub.replace(unResolvedProps.get(key)); 
      resolvedProps.put(key, value); 
     } 
     return resolvedProps; 
    } 
} 

कॉन्फ़िगरेशन फ़ाइल «आप संदर्भ को नजरअंदाज किया जा करना चाहते हैं और बदला नहीं जाएगा, तो आप प्रारूप नीचे का उपयोग कर सकते हैं।

$${${name}} must be used for output ${ Yash }. EX: jdk = ${jre-1.8} 

फ़ाइल: keys_ReferedKeys.properties

# MySQL Key for each developer for their local machine 
dbIP  = 127.0.0.1 
dbName  = myApplicationDB 
dbUser  = scott 
dbPassword = tiger 

# MySQL Properties 
# To replace fixed-keys with corresponding build environment values. like « predev,testing,preprd. 
config.db.driverClassName : com.mysql.jdbc.Driver 
config.db.url    : jdbc:mysql://${dbIP}:3306/${dbName} 
config.db.username  : ${dbUser} 
config.db.password  : ${dbPassword} 

# SystemProperties 
userDir  = ${user.dir} 
os.name  = ${os.name} 
java.version = ${java.version} 
java.specification.version = ${java.specification.version} 

# If you want reference to be ignored and won't be replaced. 
# $${${name}} must be used for output ${ Yash }. EX: jdk = ${jre-1.8} 
jdk = $${jre-${java.specification.version}} 

जावा गुण (कुंजी = मान) प्रारूप उदाहरण log4j.properties

संबंधित मुद्दे