سؤال

يتضمن مشروعي العديد من المكونات الإضافية وكل مكون إضافي يتضمن ملف plugin.properties مع ما يقرب من 20 ترجمة.يحدد ملف MANIFEST.MF اسم ملفات الخصائص حيث يتم تخزين سلاسل البرنامج المساعد الخارجية.

Bundle-Localization: plugin

اسم البرنامج المساعد الذي أعرفه مثل

%plugin.name

سيبحث Eclipse عن "%plugin.name" في ملف plugin.properties في وقت التشغيل.

ما هي الفئة التي تقرأ إدخال MANIFEST.MF Bundle-Localization وعند أي نقطة يتم البحث عن السلسلة التي تحتوي على لاحقة البداية '%' في ملف "plugin.properties"؟

أريد العثور على هذه الفئة وتصحيحها بهذه الطريقة، حتى أتمكن أولاً من البحث في بعض الدلائل/الملفات الأخرى عن معرف "%plugin.name".باستخدام هذه الآلية الجديدة، يمكنني إضافة أجزاء إلى منتجي واستبدال الأسطر المفردة في ملف "plugin.properties" دون تغيير المكون الإضافي الأصلي.باستخدام هذه الآلية، يمكنني إنشاء عملية بناء لعدة عملاء فقط عن طريق إضافة أجزاء مختلفة.الأجزاء بما في ذلك أسماء العملاء والسلسلة الخاصة التي يريدون تغييرها.

أريد أن أفعل ذلك بهذه الطريقة، لأن آلية التجزئة تضيف فقط الملفات إلى البرنامج المساعد الأصلي.عندما يكون الملف "plugin.properties" موجودًا في البرنامج الإضافي، يتم تجاهل ملفات "plugin.properties" المجزأة.

التحديث 1:

طريقة

class ManifestLocalization{
...
protected ResourceBundle getResourceBundle(String localeString) {
}
...
}

تقوم بإرجاع ResourceBundle لملف الخصائص لسلسلة الإعدادات المحلية المحددة.عندما يعرف شخص ما كيف يمكنني الآن النظر أولاً في الجزء للحصول على مسار المورد، يرجى نشره.

التحديث 2:

الطريقة في فئة ManifestLocalization

    private URL findInResolved(String filePath, AbstractBundle bundleHost) {

        URL result = findInBundle(filePath, bundleHost);
        if (result != null)
            return result;
        return findInFragments(filePath, bundleHost);
    }

يبحث عن ملف الخصائص ويخزنه مؤقتًا.يمكن الحصول على الترجمات من الملف المخزن مؤقتًا.المشكلة هي أن الملف الكامل مخزّن مؤقتًا وليس ترجمات فردية.

سيكون الحل هو قراءة الملف المجزأ أولاً، ثم قراءة ملف الحزمة.عندما يكون كلا الملفين موجودين، ادمجهما في ملف واحد واكتب ملف الخصائص الجديد على القرص.يتم إرجاع عنوان URL لملف الخصائص الجديد، بحيث يمكن تخزين ملف الخصائص الجديد مؤقتًا.

هل كانت مفيدة؟

المحلول

مع العلم أني أخطأت في المعلومة..كان لي بالضبط نفس المشكلة.لم يتم تنشيط المكون الإضافي مرتين ولا يمكنني الوصول إلى مفتاح تعريب حزمة الأجزاء.

أريد كل ترجماتي اللغوية في plugin.properties (أعلم أن هذا الأمر غير مقبول ولكن من الأسهل بكثير إدارة ملف واحد).

لقد (نصف) حل المشكلة باستخدام

public void populate(Bundle bundle) {
    String localisation = (String) bundle.getHeaders().get("Bundle-Localization");
    Locale locale = Locale.getDefault();

    populate(bundle.getEntry(getFileName(localisation)));
    populate(bundle.getEntry(getFileName(localisation, locale.getLanguage())));
    populate(bundle.getEntry(getFileName(localisation, locale.getLanguage(), locale.getCountry())));
    populate(bundle.getResource(getFileName("fragment")));
    populate(bundle.getResource(getFileName("fragment", locale.getLanguage())));
    populate(bundle.getResource(getFileName("fragment", locale.getLanguage(), locale.getCountry())));
}

وقم ببساطة بتسمية ملف ترجمة الأجزاء الخاص بي "fragment.properties".

هذا ليس أنيقًا بشكل خاص، لكنه يعمل.

بالمناسبة، للحصول على ملفات من الجزء، تحتاج إلى getResource، ويبدو أن ملفات الجزء موجودة في مسار الفصل، أو يتم البحث عنها فقط عند استخدام getResource.

إذا كان لدى شخص ما نهج أفضل، يرجى تصحيح لي.

أتمنى لك كل خير،

علامة.

نصائح أخرى

/**
 * The Hacked NLS (National Language Support) system.
 * <p>
 * Singleton.
 * 
 * @author mima
 */
public final class HackedNLS {
    private static final HackedNLS instance = new HackedNLS();

    private final Map<String, String> translations;

    private final Set<String> knownMissing;

    /**
     * Create the NLS singleton. 
     */
    private HackedNLS() {
        translations = new HashMap<String, String>();
        knownMissing = new HashSet<String>();
    }

    /**
     * Populates the NLS key/value pairs for the current locale.
     * <p>
     * Plugin localization files may have any name as long as it is declared in the Manifest under
     * the Bundle-Localization key.
     * <p>
     * Fragments <b>MUST</b> define their localization using the base name 'fragment'.
     * This is due to the fact that I have no access to the Bundle-Localization key for the
     * fragment.
     * This may change.
     * 
     * @param bundle The bundle to use for population.
     */
    public void populate(Bundle bundle) {
        String baseName = (String) bundle.getHeaders().get("Bundle-Localization");

        populate(getLocalizedEntry(baseName, bundle));
        populate(getLocalizedEntry("fragment", bundle));
    }

    private URL getLocalizedEntry(String baseName, Bundle bundle) {
        Locale locale = Locale.getDefault();
        URL entry = bundle.getEntry(getFileName(baseName, locale.getLanguage(), locale.getCountry()));
        if (entry == null) {
            entry = bundle.getResource(getFileName(baseName, locale.getLanguage(), locale.getCountry()));
        }
        if (entry == null) {
            entry = bundle.getEntry(getFileName(baseName, locale.getLanguage()));
        }
        if (entry == null) {
            entry = bundle.getResource(getFileName(baseName, locale.getLanguage()));
        }
        if (entry == null) {
            entry = bundle.getEntry(getFileName(baseName));
        }
        if (entry == null) {
            entry = bundle.getResource(getFileName(baseName));
        }
        return entry;
    }

    private String getFileName(String baseName, String...arguments) {
        String name = baseName;
        for (int index = 0; index < arguments.length; index++) {
            name += "_" + arguments[index];
        }
        return name + ".properties";
    }

    private void populate(URL resourceUrl) {
        if (resourceUrl != null) {
            Properties props = new Properties();
            InputStream stream = null;
            try {
                stream = resourceUrl.openStream();
                props.load(stream);
            } catch (IOException e) {
                warn("Could not open the resource file " + resourceUrl, e);
            } finally {
                try {
                    stream.close();
                } catch (IOException e) {
                    warn("Could not close stream for resource file " + resourceUrl, e);
                }
            }
            for (Object key : props.keySet()) {
                translations.put((String) key, (String) props.get(key));
            }
        }
    }

    /**
     * @param key The key to translate.
     * @param arguments Array of arguments to format into the translated text. May be empty.
     * @return The formatted translated string.
     */
    public String getTranslated(String key, Object...arguments) {
        String translation = translations.get(key);
        if (translation != null) {
            if (arguments != null) {
                translation = MessageFormat.format(translation, arguments);
            }
        } else {
            translation = "!! " + key;
            if (!knownMissing.contains(key)) {
                warn("Could not find any translation text for " + key, null);
                knownMissing.add(key);
            }
        }
        return translation;
    }

    private void warn(String string, Throwable cause) {
        Status status;
        if (cause == null) {
            status = new Status(
                    IStatus.ERROR, 
                    MiddlewareActivator.PLUGIN_ID, 
                    string);
        } else {
            status = new Status(
                IStatus.ERROR, 
                MiddlewareActivator.PLUGIN_ID, 
                string,
                cause);
        }
        MiddlewareActivator.getDefault().getLog().log(status);

    }

    /**
     * @return The NLS instance.
     */
    public static HackedNLS getInstance() {
        return instance;
    }

    /**
     * @param key The key to translate.
     * @param arguments Array of arguments to format into the translated text. May be empty.
     * @return The formatted translated string.
     */
    public static String getText(String key, Object...arguments) {
        return getInstance().getTranslated(key, arguments);
    }
}

قم بتغيير اسم الجزء الخاص بك من plugin.properties إلى شيء آخر، على سبيل المثال.جزء.خصائص

في ظهور شظاياك ، قم بتغيير توحيد الحزمة:المكون الإضافي إلى توحيد الحزمة:شظية

سيتم تنشيط المكون الإضافي الخاص بك مرتين، المرة الأولى باستخدام plugin.properties، والثانية باستخدام fragment.properties.

تتم معالجة تنشيط البرنامج المساعد بواسطة Equinox لوقت تشغيل OSGi.ومع ذلك فإنني لا أشجع بشدة على محاولة تصحيح أي ملفات هناك لإنشاء سلوك معين.تبدو الطريقة المقترحة من مارك طريقة أكثر عقلانية لحل مشكلتك.

تتمثل إحدى الطرق في إرفاق مستمع حزمة، والاستماع إلى عمليات تثبيت الحزم (وربما أيضًا إلقاء نظرة على الحزم المثبتة بالفعل) ولكل حزمة إنشاء/توفير - وتثبيت - جزء يحتوي على ملفات الخصائص المطلوبة.إذا تم ذلك قبل بدء تشغيل التطبيق، فيجب أن يكون لذلك تأثير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top