2011-11-21 10 views
6

हमारे अनुप्रयोगों में हम संपत्ति फ़ाइलों का बहुत उपयोग कर रहे हैं। कुछ महीनों से मैंने अमरूद सीखना शुरू कर दिया है और मुझे यह वास्तव में बहुत पसंद आया।संपत्ति फ़ाइलों से गुवा के साथ वस्तुओं का निर्माण

Map<String, Datasource> बनाने का सबसे अच्छा तरीका क्या है?

संपत्ति फ़ाइल प्रारूप सख्त नहीं है। इसे बदला जा सकता है अगर इसे किसी अन्य प्रारूप के साथ बेहतर व्यक्त किया जा सकता है?

नमूना संपत्ति फ़ाइल:

datasource1.url=jdbc:mysql://192.168.11.46/db1 
datasource1.password=password 
datasource1.user=root 
datasource2.url=jdbc:mysql://192.168.11.45/db2 
datasource2.password=password 
datasource2.user=root 

उत्तर

5

गुण वर्ग HashTable, का एक उपवर्ग है जो बदले में मानचित्र को लागू करता है।

आप हमेशा की तरह इसे लोड के साथ:

Properties properties = new Properties(); 
    try { 
     properties.load(new FileInputStream("filename.properties")); 
    } catch (IOException e) { 
} 

संपादित करें: ठीक है तो आप नक्शे पर < स्ट्रिंग, डेटा स्रोत > यह बदलना चाहते हैं;)

//First convert properties to Map<String, String> 
Map<String, String> m = Maps.fromProperties(properties); 

//Sort them so that password < url < user for each datasource and dataSource1.* < dataSource2.*. In your case default string ordering is ok so we can take a normal treemap 
Map<String, String> sorted = Maps.newTreeMap(); 
sorted.putAll(m); 

//Create Multimap<String, List<String>> mapping datasourcename->[password,url, user ] 

    Function<Map.Entry<String, String>, String> propToList = new Function<String, Integer>() { 
     @Override 
     public String apply(Map.Entry<String, String> entry) { 
      return entry.getKey().split("\\.")[0]; 
     } 
    }; 

Multimap<Integer, String> nameToParamMap = Multimaps.index(m.entrySet(), propToList); 

//Convert it to map 
Map<String, Collection<String>> mm = nameToParamMap.asMap(); 

//Transform it to Map<String, Datasource> 
Map<String, Datasource> mSD = Maps.transformEntries(mm, new EntryTransformer<String, Collection<String>, DataSource>() { 
     public DataSource transformEntry(String key, Collection<String> value) { 
      // Create your datasource. You know by now that Collection<String> is actually a list so you can assume elements are in order: [password, url, user] 
      return new Datasource(.....) 
     } 
     }; 

//Copy transformed map so it's no longer a view 
Map<String, Datasource> finalMap = Maps.newHashMap(mSD); 

संभवतः एक आसान तरीका है, लेकिन यह काम करना चाहिए :)

फिर भी आप जेसन या एक्सएमएल के साथ बेहतर हैं। आप विभिन्न फाइलों के विभिन्न डेटा स्रोतों के गुण भी लोड कर सकते हैं।

EDIT2: कम अमरूद, अधिक जावा के साथ:

//Sort them so that password < url < user for each datasource and dataSource1.* < dataSource2.*. In your case default string ordering is ok so we can take a normal SortedSet 
SortedSet <String> sorted = new SortedSet<String>(); 
sorted.putAll(m.keySet); 

//Divide keys into lists of 3 
Iterable<List<String>> keyLists = Iterables.partition(sorted.keySet(), 3); 


Map<String, Datasource> m = new HashMap<String, Datasource>(); 
for (keyList : keyLists) { 
    //Contains datasourcex.password, datasroucex.url, datasourcex.user 
    String[] params = keyList.toArray(new String[keyList.size()]); 
    String password = properties.get(params[0]); 
    String url = properties.get(params[1]); 
    String user = properties.get(params[2]); 
    m.put(params[0].split("\\.")[0], new DataSource(....) 
} 
+0

मुझे इसके बारे में पता है लेकिन इसके बाद आप क्या बनाने का सुझाव दे रहे हैं मानचित्र <स्ट्रिंग, डेटासोर्स> – Cemo

+0

आप मेरे समाधान में कुछ पंक्तियां सहेज सकते हैं। मैंने उन्हें छोड़ दिया ताकि यह और अधिक पठनीय हो। – soulcheck

+0

मैंने मतदान किया :) लेकिन मैं थोड़ा और इंतजार करना चाहता हूं। धन्यवाद :) जिस तरह से पहली बार सवाल के अस्पष्ट के लिए खेद है। Stackoverflow इसे अनदेखा :) – Cemo

0

हैं फ़ाइल है कि आप विन्यास के लिए उपयोग कर रहे हैं सख्त नहीं है, आप एक XML फ़ाइल का उपयोग defintion स्टोर करने के लिए कर सकता है।

उदाहरण परिभाषा:

<resources> 
<configuration> 
    <datasrouce> 
    <connection name="" url="" password="" user=""/> 
    <connection name="" url="" password="" user=""/> 
    </datasource> 
</configuration> 
</resources> 

तुम सिर्फ कनेक्शन की जानकारी प्राप्त करने के लिए एक्सएमएल पढ़ सकते हैं और कनेक्शन का एक उदाहरण बना सकते हैं और संघीय रूप से प्रबंधित कर सकता है एक कनेक्शन प्रबंधक वर्ग का उपयोग कर।

6

सबसे आसान काम शायद JSON उपयोग करने के लिए है एक गुण इस के लिए फ़ाइल के बजाय:

{ 
    "datasources": [ 
    { 
     "name": "datasource1", 
     "url": "jdbc:mysql://192.168.11.46/db1", 
     "user": "root", 
     "password": "password" 
    }, 
    { 
     "name": "datasource2", 
     "url": "jdbc:mysql://192.168.11.46/db2", 
     "user": "root", 
     "password": "password" 
    } 
    ] 
}

तो फिर तुम सिर्फ एक पुस्तकालय ऐसे Gson के रूप में उपयोग कर सकते हैं कि कन्वर्ट करने के लिए वस्तुओं में:

public class DataSources { 
    private List<DataSourceInfo> dataSources; 

    public Map<String, DataSource> getDataSources() { 
    // create the map 
    } 
} 

public class DataSourceInfo { 
    private String name; 
    private String url; 
    private String user; 
    private String password; 

    // constructor, getters 
} 

फिर मानचित्र प्राप्त करने के लिए:

Gson gson = new Gson(); 
Map<String, DataSource> dataSources = gson.fromJson(/* file or stream here */, 
    DataSources.class).getDataSources(); 
+0

मैंने विचार और सुरुचिपूर्ण समाधान के कारण मतदान किया और मैं आपके द्वारा सुझाए गए समाधान का भी उपयोग करूँगा लेकिन प्रश्न के उत्तर में फिट करने के लिए मैं एक और चुनता हूं। :) कॉलिन के रास्ते से, मैं भी आप का बड़ा प्रशंसक हूं। :) आपके योगदान के लिए धन्यवाद। हालांकि मैं बेहतर सीखने के लिए आपके एक और अद्भुत कार्यान्वयन को भी देखना चाहता था। ;) – Cemo

+0

@Sessizlik मुझे लगता है कि मेरा बिंदु नौकरी के लिए सही उपकरण का उपयोग करना है।आपके पास यहां कुछ संरचित डेटा है जिसे आप पढ़ना चाहते हैं। गुण फ़ाइलें फ्लैट हैं और संरचना को अच्छी तरह से व्यक्त नहीं करते हैं। अमरूद उस तथ्य को नहीं बदलता है। जीसन (आकस्मिक रूप से Google की JSON रूपांतरण लाइब्रेरी) अधिक उपयुक्त लगता है और यह इसे आसान बनाता है। – ColinD

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