2010-04-09 16 views
14

हमारे पास बहुत सारे स्ट्रिंग्स थे जिनमें कंपनी या उत्पाद नाम वाले ब्रांडिंग जैसी स्ट्रिंग्स के लिए लॉग की जांच करने या समर्थन से संपर्क करने के बारे में वाक्य से समान उप-स्ट्रिंग शामिल थी। पुनरावृत्ति हमारे लिए कुछ मुद्दों का कारण बन रही थी (मुख्य रूप से टाइपो या प्रतिलिपि/पेस्ट त्रुटियां) लेकिन इससे समस्याएं भी होती हैं जिससे हमारे अनुवादक को अनुवाद करने की मात्रा बढ़ जाती है।मैं जावा संसाधन बंडल तारों में पुनरावृत्ति से कैसे बचूं?

समाधान मैं के साथ आया था कुछ इस तरह चला गया: असली संसाधन बंडल को

public class ExpandingResourceBundleControl extends ResourceBundle.Control { 
    public static final ResourceBundle.Control EXPANDING = 
    new ExpandingResourceBundleControl(); 

    private ExpandingResourceBundleControl() { } 

    @Override 
    public ResourceBundle newBundle(String baseName, Locale locale, String format, 
            ClassLoader loader, boolean reload) 
    throws IllegalAccessException, InstantiationException, IOException { 

     ResourceBundle inner = super.newBundle(baseName, locale, format, loader, reload); 
     return inner == null ? null : new ExpandingResourceBundle(inner, loader); 
    } 
} 

ExpandingResourceBundle प्रतिनिधियों लेकिन {{this.kind.of.thing}} में महत्वपूर्ण को देखने के लिए की रूपांतरण करता संसाधन।

हर बार जब आप इनमें से किसी एक को प्राप्त करना चाहते हैं, तो आप तय करना है:

ResourceBundle.getBundle("com/acme/app/Bundle", EXPANDING); 

और यह ठीक काम करता है - थोड़ी देर के लिए।

अंततः क्या होता है यह है कि कुछ नए कोड (हमारे मामले में स्वत: जेनरेट कोड जो मैटिस से बाहर था) कस्टम नियंत्रण निर्दिष्ट किए बिना एक ही संसाधन बंडल को देखता है। यह गैर-प्रतिलिपि प्रतीत होता है यदि आप एक साधारण इकाई परीक्षण लिखते हैं जो इसे बिना और उसके बिना कॉल करता है, लेकिन ऐसा तब होता है जब एप्लिकेशन वास्तविक के लिए चलाया जाता है। किसी भी तरह ResourceBundle के अंदर कैश अच्छा मूल्य निकालता है और इसे टूटे हुए के साथ बदल देता है। मुझे अभी पता लगाना बाकी है कि क्यों और सूर्य की जार फ़ाइलों को डीबग जानकारी के बिना संकलित किया गया था, इसलिए इसे डिबगिंग करना एक गड़बड़ है।

मेरे सवालों का:

  1. वहाँ विश्व स्तर पर डिफ़ॉल्ट ResourceBundle.Control है कि मैं के बारे में पता नहीं हो सकता है की स्थापना के कुछ रास्ता नहीं है? यह सब कुछ सुन्दरता से हल करेगा।

  2. क्या इस तरह की चीज को सुन्दर तरीके से संभालने का कोई और तरीका है, शायद संसाधनबंडल कक्षाओं के साथ छेड़छाड़ किए बिना?

+0

कुछ है जो आसानी से, metaprogramming का उपयोग कर नियंत्रित किया जा सकता है अगर जावा यह था कि। –

उत्तर

6

मुझे लगता है कि इस तरह से ResourceBundles कार्य करने के लिए तैयार कर रहे हैं में एक मौलिक दोष है: कुंजी है कि अन्य कुंजी संदर्भ स्वचालित रूप से सूखी (अपने आप को दोहराने नहीं है) सिद्धांत का उल्लंघन। जिस तरह से मैं इसे प्राप्त करता हूं वह आपकी विधि के समान था: एक प्रतिबिंबित संसाधन संसाधन बनाएं जो आपको ईएल नोटेशन का उपयोग कर संदेशों में संसाधन कुंजी निर्दिष्ट करने की अनुमति देता है।

गलत तरीके:

my.name.first=Bob 
my.name.last=Smith 
my.name.full=Bob Smith 

सही रास्ता:

my.name.first=Bob 
my.name.last=Smith 
my.name.full=${my.name.first} ${my.name.last} 

मैं गया है uploaded the code to GitHub तो आप या किसी और इसे डाउनलोड कर सकते हैं। इसके अतिरिक्त, मैंने आपको तेजी से चलने और चलाने के लिए स्ट्रिप्स फ्रेमवर्क (http://www.stripesframework.org/) का उपयोग करके किसी भी व्यक्ति के लिए कुछ नमूना कोड जोड़ा है।

मानक जेएसटीएल एफएमटी टैगलिब्स के साथ काम करने के लिए यह एक इंटरसेप्टर स्थापित करना था जो एचटीपीएसर्लेट रिवेस्ट के संसाधन को अपने आप से बदल देता था। कोड इस तरह कुछ दिखता है:

ResourceBundle bundle = MyStaticResourceHoldingTheBundle.getBundle(); 
Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale)); 

अधिक जानकारी के लिए उपरोक्त लिंक में stripes.interceptor पैकेज पर एक नज़र डालें।

+0

आप सही हैं, यह हमारे समाधान के समान ही है, और इसमें वही कमी है जो संसाधन Bundle.getBundle() का उपयोग करके जेनरेट किया गया कोड वर्कअराउंड प्राप्त नहीं करेगा। प्राथमिक अंतर यह है कि हमारे मामले में हम मौजूदा संसाधन बंडल कैश का उपयोग करते हैं, जबकि आपके मामले में आप कैश को अलग से रखते हैं, संभवतः सूर्य के कैश के आसपास काम करने के लिए कैश किए गए बंडलों को पकड़ना। – Trejkaz

+0

क्योंकि मैं सिर्फ एक ही मुद्दे पर ठोकर हुआ: मैं मूल रूप से करने के लिए फिर से उपयोग ResourceBundle की सभी सुविधाओं का था, लेकिन कुंजी विस्तार जोड़ें। इसलिए मैंने प्रॉपर्टी रिसोर्सबंडल से व्युत्पन्न किया है और इसके अनुसार हैंडल GetObject() तदनुसार (जैसा कि मैट ब्रॉक्स स्रोतों में देखा जा सकता है)। मैं तो ResourceBundle.Control से ली गई, overrode newBundle() अपने कस्टम PropertyResourceBundle वापस जाने के लिए (बस इस विधि के लिए मूल स्रोत संशोधित) और ResourceBundle.getBundle करने के लिए इसे पारित कर दिया()। यह संसाधन संसाधन बंडल की सभी सुविधाओं का पुन: उपयोग करना संभव बनाता है + कुंजी-विस्तार जोड़ें। – quaylar

+0

@ मैट ब्रॉक, ऐसा लगता है कि लिंक टूटा हुआ है। क्या आप पेज साझा कर सकते हैं? –

0

स्ट्रिंग repetitions अर्थ है कि आप जानते हैं कि एक निश्चित स्ट्रिंग दोहराया जाएगा, लेकिन केवल एक ही परियोजना के भीतर ऐसी है कि साझा करने संसाधन बंडलों एक डिजाइन बुरा सपना नहीं है में स्थानीयकृत हैं, तो आप तार टूट सोच सकते हैं एकाधिक कुंजी-मूल्य भागों में। उन हिस्सों को अलग करें जो दोहराए गए हिस्सों का पुन: उपयोग नहीं करते हैं। उदाहरण के लिए, आपको निम्न दो तार आप प्रदर्शित करने के लिए की जरूरत है कहते हैं की सुविधा देता है: "। लाल से ढकी रॉबिन ऑस्ट्रेलिया के लिए एक छोटे गौरैया पक्षी निवासी है"

  1. "लाल से ढकी रॉबिन में पाया जाता है अधिकांश महाद्वीप में ड्रायर क्षेत्रों। "

संसाधन बंडल के रूप में निम्नानुसार हो सकता है:

robin.name=The Red-capped Robin 
robin.native=is a small passerine bird native to Australia. 
robin.region=is found in dryer regions across much of the continent. 

और फिर आवश्यक भागों जहां जरूरत bundle.getString("robin.name")+bundle.getString(robin.native).

एक बात आपको सावधान रहने की के बारे में है, हालांकि जरूरत गठबंधन है कि इस विषय की तरह व्याकरण के नियमों भविष्यवाणी आदेश आदि सभी भाषाओं में समान नहीं हो सकता है। तो वाक्यों को विभाजित करते समय आपको थोड़ा सावधान रहना होगा।

+5

असल में वह भी, एक बुरा (आदि 1, 2, 27,) विभिन्न संदर्भों (जैसे एक मेनू पर या एक स्थिति पट्टी में) के लिए विचार, विषय के लिंग, और बहुलता है, क्योंकि ये भी संस्कृति के आधार पर बदल जाते हैं। – devstuff

+0

यह वास्तव में सटीक कारण है कि हम संसाधन बंडल पक्ष से सभी प्रविष्टियों को करने के दृष्टिकोण के साथ गए थे। हमारे वर्तमान दृष्टिकोण के साथ उदाहरण {{robin.name}} को नीचे दिए गए मानों में उचित स्थान पर डालकर किया जाएगा। अगर किसी को ऐसी भाषा का सामना करना पड़ता है जहां यह काम नहीं करेगा, तो उनके पास चर को पूरी तरह हटाने की शक्ति है। लेकिन ... हमारा समाधान सही तरीके से काम करने के लिए मुश्किल है। – Trejkaz

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