Notes Plugin: Where are Custom User Settings Stored? - plugins

We've developed a custom plugin for Notes 8.5.2. It records a number of custom user preferences. The class that does so is shown below:
import java.util.prefs.Preferences;
/**
* Provides programmatic access to Windows Registry entries for this plug-in.
*/
public class Registry
{
Preferences prefs;
/**
* Initializes a new instance of the Registry class.
*/
public Registry()
{
prefs = Preferences.userNodeForPackage(Registry.class) ;
}
/**
* Gets the value of a registry key.
*
* #param keyName The name of the key to return.
*
* #return A string containing the value of the specified registry key. If a key with the specified name cannot be
* found, the return value is an empty string.
*/
public String GetValue(String keyName)
{
try
{
return prefs.get(keyName, "NA") ;
}
catch(Exception err)
{
return "" ;
}
}
/**
* Sets the value of a registry key.
*
* #param keyName The name of the registry key.
*
* #param keyValue The new value for the registry key.
*/
public void SetValue(String keyName, String keyValue)
{
try
{
prefs.put(keyName, keyValue);
prefs.flush();
}
catch(Exception err)
{
}
}
}
A sample of the code that uses it is as follows:
Registry wr = new Registry();
String setting1 = wr.GetValue("CustomSetting1");
wr.SetValue("CustomSetting1", newValue);
Now, I've scanned the Windows Registry, and these settings do not exist. I've indexed my entire hard disk, and I cannot find these entries in any file.
So, where the heck are these settings being stored?

On Windows the Java Preferences API uses the Registry as it's backing store for the Preferences class. The keys are rooted by package name under HKEY_CURRENT_USER\Software\JavaSoft\Prefs.
Your code doesn't specify a package, so it uses the following location by default (tested on Windows Vista and 7):
HKEY_CURRENT_USER\Software\JavaSoft\Prefs\<unnamed>
There is an articled titled "Sir, What is Your Preference?" by Ray Djajadinataz at the Sun Developer Network where you can get a little more background on this API with some screen shots showing registry locations.
I wonder if you were searching for the key name, eg CustomSetting1, and not finding it because it is saved as /Custom/Setting1 to note that the C and S are capitalized (see API docs.)

Related

Replace the rendering engine of a composition Moodle 4.1?

I tried to follow Moodle’s documentation on how to replace a rendering engine, but it doesn’t work for some reason.
I have created a theme following the documentation steps and Then I created a renderers.php file at the root of my project. I added the following lines of code in the renderers.php file:
class theme_overridetest_core_calendar_renderer extends core_calendar_renderer {
/**
* Disabled creation of the button to add a new event (Was: Creates a button to add a new event)
*
* #param int $courseid
* #param int $day
* #param int $month
* #param int $year
* #return string
*/
protected function add_event_button($courseid, $day=null, $month=null, $year=null) {
return '';
}
}
After reviewing the documentation I read a passage that dissatisfied that this way of proceeding was for the older versions of Moodle, I would like to know the one used for version 4.1

Private key from environment variable instead of file in Google Cloud Firestore

I need to connect to Google Cloud Firestore from my Next.js serverless function hosted in Vercel. I already have a service account set up, but all the docs out there rely on the credentials being a file, while I'd like to use environment variables (more natural in Vercel platform).
Example:
const Firestore = require('#google-cloud/firestore');
const firestore = new Firestore({
projectId: 'YOUR_PROJECT_ID',
keyFilename: '/path/to/keyfile.json',
});
I cannot use keyFilename, I'd rather pass the service account email and private key explicitly.
Working code:
const projectId = process.env.GOOGLE_PROJECT_ID;
const email = process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL;
const key = process.env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n');
const Firestore = require('#google-cloud/firestore');
const firestore = new Firestore({
projectId: projectId,
credentials: {
client_email: email,
private_key: key,
},
});
Please note that my GOOGLE_PRIVATE_KEY env var has literal \ns, exactly as Google Cloud's JSON comes, so I use .replace() on it to translate them to actual newlines. This is actually only needed in my local environment, where I use .env.local, since Vercel env vars can take actual newlines.
Source
The settings object (argument for the constructor Firestore()) is poorly documented, but I was able to figure it out by myself grepping through the source code, where I found:
node_modules/#google-cloud/firestore/types/firestore.d.ts
Line 217:
/**
* Settings used to directly configure a `Firestore` instance.
*/
export interface Settings {
/**
* The project ID from the Google Developer's Console, e.g.
* 'grape-spaceship-123'. We will also check the environment variable
* GCLOUD_PROJECT for your project ID. Can be omitted in environments that
* support {#link https://cloud.google.com/docs/authentication Application
* Default Credentials}
*/
projectId?: string;
/** The hostname to connect to. */
host?: string;
/** The port to connect to. */
port?: number;
/**
* Local file containing the Service Account credentials as downloaded from
* the Google Developers Console. Can be omitted in environments that
* support {#link https://cloud.google.com/docs/authentication Application
* Default Credentials}. To configure Firestore with custom credentials, use
* the `credentials` property to provide the `client_email` and
* `private_key` of your service account.
*/
keyFilename?: string;
/**
* The 'client_email' and 'private_key' properties of the service account
* to use with your Firestore project. Can be omitted in environments that
* support {#link https://cloud.google.com/docs/authentication Application
* Default Credentials}. If your credentials are stored in a JSON file, you
* can specify a `keyFilename` instead.
*/
credentials?: {client_email?: string; private_key?: string};
/** Whether to use SSL when connecting. */
ssl?: boolean;
/**
* The maximum number of idle GRPC channels to keep. A smaller number of idle
* channels reduces memory usage but increases request latency for clients
* with fluctuating request rates. If set to 0, shuts down all GRPC channels
* when the client becomes idle. Defaults to 1.
*/
maxIdleChannels?: number;
/**
* Whether to use `BigInt` for integer types when deserializing Firestore
* Documents. Regardless of magnitude, all integer values are returned as
* `BigInt` to match the precision of the Firestore backend. Floating point
* numbers continue to use JavaScript's `number` type.
*/
useBigInt?: boolean;
/**
* Whether to skip nested properties that are set to `undefined` during
* object serialization. If set to `true`, these properties are skipped
* and not written to Firestore. If set `false` or omitted, the SDK throws
* an exception when it encounters properties of type `undefined`.
*/
ignoreUndefinedProperties?: boolean;
[key: string]: any; // Accept other properties, such as GRPC settings.
}

How can I add language setting entries to existing CDT eclipse projects?

I am following the steps found here to try to add build settings to files in existing Eclipse CDT projects using the LanguageSettingsProvider extension point, but my settings provider doesn't seem to show in the UI, and its methods aren't queried for settings.
I previously succeeded in adding settings to a project using an external settings provider, but I couldn't find a way to add file-specific settings.
I have implemented a subclass of LanguageSettingsSerializableProvider (let's call it MyProvider), and added it to my plugin.xml thus:
<extension
point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider
class="com.example.MyProvider"
id="MyProvider_id"
name="I would like to see this in the UI">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
The class is implemented approximately thus:
public class MyProvider
extends LanguageSettingsSerializableProvider
implements ILanguageSettingsProvider,
IResourceChangeListener,
ILanguageSettingsEditableProvider,
ILanguageSettingsBroadcastingProvider {
/** The ID of this settings provider */
public static final String MY_PROVIDER_ID = "MyProvider_id"; //$NON-NLS-
/**
* Constructor. Initialises super class with appropriate values.
*/
public MyProvider() {
super( MY_PROVIDER_ID , Messages.UiLabel );
}
#Override
public String getId() {
return MY_PROVIDER_ID ;
}
#Override
public String getName() {
return Messages.UiLabel;
}
#Override
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource resource, String languageId) {
//breakpoint on this line that never gets hit...
return super.getSettingEntries( cfgDescription, resource, languageId );
}
...
}
The real implementation contains some other logic to actually create the settings entries, including registering itself as a resource change listener. The resourceChanged code works fine, calls setSettingsEntries, and then serializeSettings. However, getSettingEntries is never called to obtain these settings.
Is there something I'm missing?
My guess is the plugin.xml is lacking something, but I'm not sure what. There are paragraphs of guidance in the various interfaces that the class implements, but one simple working example would be worth more than a thousand words. I've tried looking at the xml for the built-in settings providers (e.g. GCCBuiltinCompilerSettingsMinGW), but they're defined alongside a lot of other parts of CDT, and it's hard to tell which bits are relevant to my use case.
What I ended up doing was:
someMethod {
final IProject myProject = getProjectFromSomewhere();
final ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription( myProject );
for (ICConfigurationDescription config : projDesc.getConfigurations()) {
try {
ensureMySettingsProvidedFor( (ILanguageSettingsProvidersKeeper) config );
} catch (ClassCastException e) {
logger.log( Level.WARNING, "Unexpected class was not a keeper of language settings:" + config.getClass().getName(), e );
}
}
}
/**
* Will ensure my settings provider is registered as a settings provider for...
* #param settingsKeeper ...the given configuration.
*/
public static void ensureMySettingsProvidedFor(final ILanguageSettingsProvidersKeeper settingsKeeper) {
if (settingsKeeper instanceof CConfigurationDescriptionCache) {
logger.log(Level.SEVERE, "Got non-writable cached settings. We can't update this!! "
+ "How do we get a writeable version?");
return;
}
for ( ILanguageSettingsProvider provider : settingsKeeper.getLanguageSettingProviders() ) {
if (MyProvider.MY_PROVIDER_ID.equals( provider.getId() )) {
return;
}
}
addMyProvider( settingsKeeper );
}
/**
* Adds my language settings provider to the given configuration by means of its ID.
* #param settingsKeeper The existing configuration.
*/
private static void addMyProvider( final ILanguageSettingsProvidersKeeper settingsKeeper ) {
List<String> ids = new ArrayList<String>();
for ( ILanguageSettingsProvider provider : settingsKeeper.getLanguageSettingProviders() ) {
ids.add( provider.getId() );
}
ids.add(MyProvider.MY_PROVIDER_ID);
List<ILanguageSettingsProvider> newProviders = LanguageSettingsManager.createLanguageSettingsProviders( ids.toArray( new String[ids.size()] ) );
settingsKeeper.setLanguageSettingProviders(newProviders);
}
It doesn't feel like the best answer, but it seems to work most of the time.
One problem is knowing when to do this such that it happens for all projects that don't yet have the provider, but doesn't get called repeatedly, or too often.
Another problem is that we sometimes get a CConfigurationDescriptionCache, and then the code can't do anything.
I'm open to better solutions.

GWT: Trouble getting value from a text box

I'm using GWT 2.4. I'm trying to submit an AJAX request with the only input being the value of a text field on the page. Here is how I attach the handler to the page's button ...
public void onModuleLoad() {
...
final com.google.gwt.dom.client.Element submitElement = Document.get().getElementById(SUBMIT_BUTTON_ID);
final Button submitButton = Button.wrap(submitElement);
...
// Add a handler to send the name to the server
GetHtmlHandler handler = new GetHtmlHandler();
submitButton.addClickHandler(handler);
}
But here's the problem. In my handler, whenever I try and get the value of the text field, it always returns the value entered in the text field when the page was first loaded, as opposed to what the most current value is ...
class GetHtmlHandler implements ClickHandler {
/**
* Fired when the user clicks on the submitButton.
*/
public void onClick(ClickEvent event) {
submitRequest();
}
/**
* Send the name from the nameField to the server and wait for a
* response.
*/
private void submitRequest() {
...
final Element nameFieldElement = DOM.getElementById(Productplus_gwt.NAME_FIELD_ID);
// This always returns an old value.
String docId = nameFieldElement.getAttribute("value");
Anyone know how I can write GWT code inside my handler to return the most current value of a text field given its page id?
Thanks, - Dave
Try using DOM.getPropertyString / DOM.getElementProperty
Following is the javadoc from GWT source for getAttribute function. It clearly says that the support for javascript's "getAttribute" function could be inconsistent for a few browsers and thus Element and subclasses should be used.
Alternatively you can use DOM.getPropertyString to fetch a value which uses object notation of javascript to get te current value
/**
* Retrieves an attribute value by name. Attribute support can be
* inconsistent across various browsers. Consider using the accessors in
* {#link Element} and its specific subclasses to retrieve attributes and
* properties.
*
* #param name The name of the attribute to retrieve
* #return The Attr value as a string, or the empty string if that attribute
* does not have a specified or default value
*/
public final String getAttribute(String name) {
return DOMImpl.impl.getAttribute(this, name);
}
I tried using javascript's "getAttribute" function to get value of a text field in IE8 and FF6. IE gave the updated value of the text field while FF did not. Here is the fiddle
http://jsfiddle.net/GvNu4/
Well like you said it's an AJAX request so whatever code you have on ... the GWT code will continue to run.
You should use the callback of the request and check the value of the nameFieldElement at that moment.

How to use the JFace FileDialog from within an Eclipse plugin in a modeless way?

I am writing an Eclipse plugin, and in response to some action I am interesting in starting a series of operations (within a separate job). One of these operations is to request the user to provide a filename, which I'm trying to do with the JFace JDialog.
However, I'm not clear how to do this in a modeless way; for example, where do I obtain a display and shell? How do I ensure the UI continues to work while the developer can edit stuff in the dialog?
May be you could see how Eclipse itself does it:
FindAndReplaceDialog.java
/**
* Creates a new dialog with the given shell as parent.
* #param parentShell the parent shell
*/
public FindReplaceDialog(Shell parentShell) {
super(parentShell);
fParentShell= null;
[...]
readConfiguration();
setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE | SWT.RESIZE);
setBlockOnOpen(false);
}
/**
* Returns this dialog's parent shell.
* #return the dialog's parent shell
*/
public Shell getParentShell() {
return super.getParentShell();
}
/**
* Sets the parent shell of this dialog to be the given shell.
*
* #param shell the new parent shell
*/
public void setParentShell(Shell shell) {
if (shell != fParentShell) {
if (fParentShell != null)
fParentShell.removeShellListener(fActivationListener);
fParentShell= shell;
fParentShell.addShellListener(fActivationListener);
}
fActiveShell= shell;
}
It does manage its parent shell depending on the focus of the Dialog.
/**
* Updates the find replace dialog on activation changes.
*/
class ActivationListener extends ShellAdapter {
/*
* #see ShellListener#shellActivated(ShellEvent)
*/
public void shellActivated(ShellEvent e) {
fActiveShell= (Shell)e.widget;
updateButtonState();
if (fGiveFocusToFindField && getShell() == fActiveShell &&
okToUse(fFindField))
fFindField.setFocus();
}
/*
* #see ShellListener#shellDeactivated(ShellEvent)
*/
public void shellDeactivated(ShellEvent e) {
fGiveFocusToFindField= false;
storeSettings();
[...]
fActiveShell= null;
updateButtonState();
}
}
A ShellAdapter is provides default implementations for the methods described by the ShellListener interface, which provides methods that deal with changes in state of Shell.
The importent thing is that the style value should include SWT.MODELESS.
The style is one of the most important things in SWT you should look at, because you can control and initialize a lot only because of the styel value.