I'm trying to find my folder or view in my database. Which named Team Documents this folder has some filter option like By Date, By Category. But this returns me a null even the folder already exists.
String dbServer = "d23dbm95/23/A/IBM", dbFileName = "dbom\\farizan\\stsklb1.nsf";
public void runNotes()
{
Session session = null;
Database db = null;
View view = null;
Document doc = null;
try
{
NotesThread.sinitThread();
session = NotesFactory.createSession();
System.out.println("User = " + session.getUserName());
db = session.getDatabase(dbServer, dbFileName);
if(db.isOpen())
{
System.out.println("Title "+db.getTitle());
view = db.getView("Team Documents \\ By Date");
if(view == null)
{
System.out.println("still null");
}
}
}
catch(NotesException e)
{
e.printStackTrace();
}
}
I tried also to fill my getView() method like Team Documents. But still returns a null. Any approach to this problem?
While it would have been more helpful if you had included a link to a screenshot of your Domino Designer client's folder list, my best guess is that you have two folders, not one folder with "filter options". Also, my guess is that "Team Documents" is not actually a folder; it's just a prefix on the folder names that makes them appear to be nested in a parent folder.
If that's the case, you would need
iew = db.getView("Team Documents\\By Category");
Or
iew = db.getView("Team Documents\\By Date");
Note: No spaces before & after the backslashes.
If my assumptions above are not correct, then my suggestion would be to assign alias names to the folders in Domino Designer and use the aliases instead of the display names in your code. Frankly, that's always a good practice, because it allows your code to continue working even if you decide to change the display names.
Related
Printscreen additional fields useradmin
How can I add some new User Properties to the CQ Users?
I found an solution but it don't work --> http://experience-aem.blogspot.ch/2014/01/aem-cq-56-extend-useradmin-add-new-user.html
I tried to manipulate in CRX the UserProperties.js with new Properties, I see them in useradmin but if I try to add the new propertie in Java Code (not via useradmin) I can save it without error, but the value is empty in useradmin.
And if I try to add some value via useradmin for the new propertie, all user gets the same value.
How can I add new User Properties, that I can set the Value via Java code like the standard properties.
user = userManager.createUser(username, password);
ValueFactory valueFactory = session.getValueFactory();
emailValue = valueFactory.createValue(email);
givennameValue = valueFactory.createValue(givenname);
nameValue = valueFactory.createValue(name);
//User class just accepts Value Object
user.setProperty("profile/" + UserProperties.EMAIL, emailValue);
user.setProperty("profile/" + UserProperties.FAMILY_NAME, nameValue);
user.setProperty("profile/" + UserProperties.GIVEN_NAME, givennameValue);
I found an solution.
Go to crx /libs/cq/security/widgets/source/widgets/security/UserProperties.js
add the fields you need in the items array of the user (Caution - there are items for user and items for groups in the same place)
in the loadRecord method of your JS, you have to add each new field to the "record" object
"items":[{
"xtype":"textfield",
"fieldLabel":CQ.I18n.getMessage("Mail"),
"anchor":"100%",
"vtype":"email",
"msgTarget":"under",
"name":"email"
},{
"xtype":"textfield",
"fieldLabel":CQ.I18n.getMessage("My Field"),
"anchor":"100%",
"msgTarget":"under",
"name":"myfield"
},{
"xtype":"textarea",
"fieldLabel":CQ.I18n.getMessage("About"),
"anchor":"100% -155",
"name":"aboutMe"
}],
loadRecord: function(rec) {
this.enableUserSaveButton(false);
this.enableGroupSaveButton(false);
var type = rec.get("type");
if (type=="user") {
this.activeForm = this.userForm;
this.hiddenForm = this.groupForm;
if (rec.id==CQ.security.UserProperties.ADMIN_ID) {
this.pwdButtons.each(function(bt) {bt.hide(); return true;} )
} else {
this.pwdButtons.each(function(bt) {bt.show(); return true;} )
}
} else {
this.activeForm = this.groupForm;
this.hiddenForm = this.userForm;
}
//is loading additional property from json and show it in formular
rec.data["myfield"] = rec.json["myfield"];
this.activeForm.getForm().loadRecord(rec);
In the java code you can then add the new properties via the "user" object to the new properties. Note that the properties are put into the subfolder "profile".
user.setProperty("profile/" + "myfield", myFieldValue);
Did you try the second approach, posted by "pedro" in the link you've posted?
It probably has to do with pushing the new field to the record:
http://experience-aem.blogspot.com/2014/01/aem-cq-56-extend-useradmin-add-new-user.html?showComment=1390804750445#c2823498719990547675
i hope this may helps you the file exist on http://[host name]:[port]/crx/de/index.jsp#/libs/cq/security/widgets/source/widgets/security/UserProperties.js
and you will have two major properties the first one is for the user this.userForm the other one is this.groupForm for groups.
I am using UnboundID-LDAPSDK (2.3.8) to change the user's photo in our Microsoft Active Directory.
LDAPConnection ldap = null;
try {
ldap = new LDAPConnection("domain-srv", 389, "CN=admin,OU=Users,OU=ADM,DC=domain,DC=local", "password");
SearchResult sr = ldap.search("DC=domain,DC=local", SearchScope.SUB, "(sAMAccountName=" + getUser().getUsername() + ")");
if (sr.getEntryCount() == 1) {
SearchResultEntry entry = sr.getSearchEntries().get(0);
entry.setAttribute("thumbnailPhoto", getUser().getPhotoAsByteArray());
ldap.close();
return true;
} else
return false;
} catch (LDAPException e) {
e.printStackTrace();
}
But I get a java.lang.UnsupportedOperationException.
The documentation for setAttribute states:
Throws an UnsupportedOperationException to indicate that this is a
read-only entry.
I also tried to change the postalCode but I get the same exception.
Changing those attributes should be possible, because I can change them with jXplorer.
Do I have to enable a write-mode somehow?
Thank you
The SearchResultEntry object extends ReadOnlyEntry and is therefore immutable. But even if it weren't, merely calling entry.setAttribute would have no effect on the data in the server. You have to use a modify operation for that.
To do that, you'd need something like:
ModifyRequest modifyRequest = new ModifyRequest(entry.getDN(),
new Modification(ModificationType.REPLACE,
"thumbnailPhoto", getUser().getPhotoAsByteArray());
ldap.modify(modifyRequest);
Also, you should put the call to ldap.close() in a finally block because as the code is written now, you're only closing the connection if the search is successful and returns exactly one entry, but not if the search fails, doesn't match any entries, or the attempt to perform the modify fails.
I'm building a tool that need access to mail specific folders (e.g. '[Gmail]/Trash', '[Gmail]/Sent'). It seems that the names are localized with respect to the user localization settings, so '[Gmail]/Trash' show as '[Gmail]/Papelera' to Spanish users for example.
I read about XLIST command but now is deprecated in favor of the IMAP LIST Extension (https://developers.google.com/gmail/imap_extensions#special-use_extension_of_the_list_command).
I tried to do it that way javax.mail.Folder.list("\Trash") but nothing is returned.
How can I use the IMAP List extension in JAVA?
PS: Using several email providers, not just Gmail.
As Bill Shannon said, You can use Gmail attributes to get special folders like Trash. But this will work only with Gmail.
javax.mail.Folder[] folders = store.getDefaultFolder().list("*");
If you print this, it should look like the following as per Gmail
a004 LIST "" "*"
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\Noselect \HasChildren) "/" "[Gmail]"
* LIST (\HasNoChildren \All) "/" "[Gmail]/All Mail"
* LIST (\HasNoChildren \Drafts) "/" "[Gmail]/Drafts"
* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important"
* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam"
* LIST (\HasNoChildren \Flagged) "/" "[Gmail]/Starred"
* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash"
a004 OK Success
Once you have the folders with you, you can iterate for the attribute you are looking for.
For [Gmail]/All Mail, mailFolder = "\\All". similarly for [Gmail]/Trash it will be mailFolder = "\\Trash"
private static IMAPFolder getLocalisedFolder(IMAPStore store, String mailFolder) throws MessagingException {
Folder[] folders = store.getDefaultFolder().list("*");
for (Folder folder : folders) {
IMAPFolder imapFolder = (IMAPFolder) folder;
for (String attribute : imapFolder.getAttributes()) {
if (mailFolder.equals(attribute)) {
return imapFolder;
}
}
}
return null;
}
This should help:
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getDefaultInstance(props, null);
javax.mail.Store store = session.getStore("imaps");
store.connect("imap.gmail.com", "myemail#gmail.com", "mypassword");
javax.mail.Folder[] folders = store.getDefaultFolder().list("*");
for (javax.mail.Folder folder : folders) {
if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0) {
System.out.println("foldername->"+folder.getFullName() + " folder msg count->" + folder.getMessageCount());
}
}
} catch (MessagingException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
You say you tried this:
javax.mail.Folder.list("\Trash")
Try without the slash:
javax.mail.Folder.list("Trash")
See how it goes. Now that's assuming that the folder is actually called "Trash". If it's localised in some other language, then you probably need to list all folders ("*"), iterate through them one by one, and find the one that gave you the \Trash attribute. I'm not very familiar with JavaMail so I don't know whether/how it gives you back the folder attributes.
maybe you can check (once you have a Folder folder) if
if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
and then check if messages in the folder have this flag:
Flags.Flag.DELETED
if so, that would mean this is the Trash? I don't remmeber if when a msg is deleted it is moved to the Trash or it can remain in the folder...if it is moved, that could make the trick.
Gmail no longer requires the use of the XLIST command. Gmail returns attributes with the regular IMAP LIST command that indicate the use of the localized mailboxes. You can access these attributes using the IMAPFolder.getAttributes method.
I'm afraid that doesn't help you if you have another IMAP server that only returns this information with XLIST.
Is it possible to rename a database already created in android?
On my apps update I would like to rename the old database and install a new then compare some values and finally delete the old.
I am doing the creation from an sqlite file in the assets folder. This is why I cannot rename all the tables and insert the new ones.
Clarification:
The old database will contain only one table that I need to compare values from against the new (from the update) database.
Both databases have been copied over from an sqlite file in the assets folder.
Once I have compared a values from the old database to new I will delete the old and use the new in its place with the values I compared.
What i was thinking of doing was rename the old create the new in its place and do everything above.
Just rename the File. Make sure the database is closed first!
Call this in your activity class:
private void renameDatabase()
{
File databaseFile = getDatabasePath("yourdb.whatever");
File oldDatabaseFile = new File(databaseFile.getParentFile(), "yourdb_old.whatever");
databaseFile.renameTo(oldDatabaseFile);
}
Response to clarification. Rename the old db (as above), copy the new one from the assets folder, open both databases and do your compare. Then delete the old file.
Lord Flash is right, you should delete the old db and copy the new oneā¦
Assuming you use a SQLiteOpenHelper, you could use a createDatabaseIfRequired(); method in getReadableDatabase() and getWritableDatabase()
private boolean checkOldDatabase() {
Log.d(Constants.LOGTAG, "OperationDbHelper.checkDatabase");
File f = new File(DB_PATH + OLD_DB_NAME);
return f.exists();
}
public void createDatabaseIfRequired() throws IOException, SQLiteException {
if (!checkOldDatabase()) {
// do db comparison / delete old db / copy new db
}
}
It's not possible to rename a sql table directly.
But you may copy it creating a new and deleting the old one.
Thanks to Kevin Galligan's answer, I was able to create a function in my Kotlin Android app that I can use whenever it might ever be necessary, to rename the database files.
If you're using Java, you'll need to change the syntax a bit but the code should hopefully be somewhat self-explanatory.
val x: String = "Hello"
//in Kotlin would be
String x = "Hello";
//in Java, for example.
Anyway, here's my code, feel free to ask questions if you have any:
private fun checkAndRenameDatabase(oldName: String, newName: String) {
val oldDatabaseFile: File = getDatabasePath(oldName)
val oldDatabaseJournal: File = getDatabasePath("${oldName}-journal")
// Can use this to check files beforehand, using breakpoints
//val files = oldDatabaseFile.parentFile.listFiles()
if(oldDatabaseFile.exists() || oldDatabaseJournal.exists()) {
db.close() // Ensure existing database is closed
val newDatabaseFile: File = getDatabasePath(newName)
val newDatabaseJournal: File = getDatabasePath("${newName}-journal")
if(oldDatabaseFile.exists()) {
if(newDatabaseFile.exists()) {
newDatabaseFile.delete()
}
oldDatabaseFile.renameTo(newDatabaseFile)
}
if(oldDatabaseJournal.exists()) {
if(newDatabaseJournal.exists()) {
newDatabaseJournal.delete()
}
oldDatabaseJournal.renameTo(newDatabaseJournal)
}
// Use with breakpoints to ensure files are now in order
//val newFiles = oldDatabaseFile.parentFile.listFiles()
// Re-open database with new name
db = SQLiteDBHelper(applicationContext, newName)
}
}
How do you set up a Test Blob Image using the yaml structure?
Also, what is the database structure for a BLOB file? (MySQL)
I have experienced the same kind of problem a while ago on a project. However as I could not find a way to solve this with the fixtures (as the database stores the blob object as a string as Pere explained above), I created a workaround to at least solve this problem in a test-case-scenario. I created the following file /app/job/Bootstrap.java:
import play.test.*;
import play.jobs.*;
import play.db.DB;
import models.*;
import java.util.List;
#OnApplicationStart
public class Bootstrap extends Job {
public void doJob() {
// Load default data if the database is empty
if(Item.count() == 0) {
Fixtures.loadModels("my_fixtures.yml");
List<Item> allItems = Item.findAll();
for (Item a: allItems){
DB.execute("UPDATE `Item` SET image='item_" + a.name.toLowerCase() + ".png|image/png' WHERE id=" + a.getId());
}
}
}
}
The first thing I do is filling the database with initial data if there are no 'Item' already stored in the database.
The second thing is iterating over all the 'Item' which play! just stored in the database, which are read from the "my_fixtures.yml" file. Here for each item the string field will get updated as shown in the example above.
I know this is not exactly the answer to question in the OP, but it gives some kind idea to work around this issue..
EDIT: In the example given above I assume that the pictures are uploaded manually to your attachment folder as given in your application.conf, and that each image name is like: "item_<item_name_in_lowercase>" with a ".png" extension
Well, play is quite weird on that point.
The blob is not saved into the database but in a upload folder defined in your application.conf. It is the path toward the file that is saved in the database.
I cannot check it right now, but I seem to recall they are saved as textuel representations (VARCHAR, TEXT)
The blob is saved in the file system, by default under "data/attachments" if I recall correctly, but you can change that in the configuration (application.conf)
In the database, it's stored as a String (varchar in most DB) with two components: the name and the mime type. It looks like:
12345asbcdefghi12345abcdfed|image/jpeg
The first part is the name of the file. When you upload a file Play generates a unique UUID as name to avoid collision. Yes, this means you are loosing the original name. (note: now I'm having doubts on the name part, I would swear it is lost, but I may be wrong!)
The second part (after the |) is the myme type. Play uses a magic-myme library to automatically detect it.
You can see the code here.
Here is a modified version of Unji's answer that loads the images from a folder in conf, please note that I have removed all the import statements:
/**
* A job executed when the application starts.
*/
#OnApplicationStart
public class Bootstrap extends Job {
/**
* Loads the initial data if there are no
* WebAdministrators at the database.
* <p>
* It loads images on the post with the following criteria:
* <ol>
* <li>file loaction: /conf/initialMedia/</li>
* <li>file name: {post.title.toCamelCase()}-{i}.jpg</li>
* </ol>
* Where i must start in 0.
* </p>
*/
#Override
public void doJob() {
// Check if the database is empty
if(WebAdministrator.count() == 0) {
Logger.info("Loading Initial Data.");
Fixtures.loadModels("initial-data.yml");
List<Post> posts = Post.findAll();
for (Post post: posts) {
Logger.info("Looking for files for post: [" + post.title + "]");
for (int i=0; true; i++) {
VirtualFile vf = VirtualFile.fromRelativePath("/conf/initialMedia/"
+ JavaExtensions.camelCase(post.title) + "-" + i + ".jpg");
File imageFile = vf.getRealFile();
if (imageFile.exists()) {
try {
Blob blobImage = new Blob();
blobImage.set(new FileInputStream(imageFile), MimeTypes.getContentType(imageFile.getName()));
MediaItem mediaItem = new Image(blobImage);
mediaItem.save();
post.mediaItems.add(mediaItem);
post.save();
Logger.info("File: [%s] Loaded", imageFile.getAbsolutePath());
} catch (FileNotFoundException e) {
// this should never happen.
}
} else {
Logger.info("Media Loaded for post [%s]: %d files.", post.title, i);
break;
}
}
}
}
}
}