lotus.domino.local.Item cannot be cast to lotus.domino.RichTextItem - xpages

I try to put a file into a richtext but it crashes !
In my first code, I try to use directly "getFirstItem", in first time it was ok but now i try to use it again and it crashed.
In second time i pass with an object and it find my obj doesn't an richtextItem (instanceof) ???
I don't understand.
I have the message : "lotus.domino.local.Item cannot be cast to lotus.domino.RichTextItem" ?
Could you help me ?
public void copieFichierDansRichText(String idDocument, String nomRti, File file,
String nameFichier, String chemin) throws NotesException {
lotus.domino.Session session = Utils.getSession();
lotus.domino.Database db = session.getCurrentDatabase();
lotus.domino.Document monDoc = db.getDocumentByUNID(idDocument);
lotus.domino.RichTextItem rtiNew = null;
try {
try {
if (monDoc != null) {
// if (monDoc.getFirstItem(nomRti) != null) {
// rtiNew = (lotus.domino.RichTextItem)
// monDoc.getFirstItem(nomRti);
// } else {
// rtiNew = (lotus.domino.RichTextItem)
// monDoc.createRichTextItem(nomRti);
// }
Object obj = null;
if (monDoc.getFirstItem(nomRti) != null) {
obj = monDoc.getFirstItem(nomRti);
if (obj instanceof lotus.domino.RichTextItem) {
rtiNew = (lotus.domino.RichTextItem) obj;
}
} else {
obj = monDoc.createRichTextItem(nomRti);
if (obj instanceof lotus.domino.RichTextItem) {
rtiNew = (lotus.domino.RichTextItem) obj;
}
}
PieceJointe pieceJointe = new PieceJointe();
pieceJointe = buildPieceJointe(file, nameFichier, chemin);
rtiNew.embedObject(EmbeddedObject.EMBED_ATTACHMENT, "", pieceJointe.getChemin()
+ pieceJointe.getNomPiece(), pieceJointe.getNomPiece());
monDoc.computeWithForm(true, false);
monDoc.save(true);
}
} finally {
rtiNew.recycle();
monDoc.recycle();
db.recycle();
session.recycle();
}
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT : I try to modify my code with yours advices but the items never considerate as richtextitem. It is my problem. I don't understand why, because in my field it is a richtext ! For it, the item can't do :
rtiNew = (lotus.domino.RichTextItem) item1;
because item1 not be a richtext !!!
I was trying to take all the fields and pass in the item one by one, and it never go to the obj instance of lotus.domini.RichTextItem....
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
// get next element from the Vector (returns java.lang.Object)
Object obj = items.elementAt(i);
// is the item a RichTextItem?
if (obj instanceof RichTextItem) {
// yes it is - cast it as such // it never go here !!
rt = (RichTextItem)obj;
} else {
// nope - cast it as an Item
item = (Item)obj;
}
}

A couple of things. First of all I would set up a util class method to handle the object recycling in a neater way:
public enum DominoUtil {
;
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
}
Secondly I would remove the reduntants try/catch blocks and simplify it like this:
private void copieFichierDansRichText(String idDocument, String nomRti, File file,
String nameFichier, String chemin) {
Session session = DominoUtils.getCurrentSession();
Database db = session.getCurrentDatabase();
Document monDoc = null;
try {
monDoc = db.getDocumentByUNID(idDocument);
Item item = monDoc.getFirstItem(nomRti);
if (item == null) {
item = monDoc.createRichTextItem(nomRti);
} else if (item.getType() != Item.RICHTEXT) {
// The item is not a rich text item
// What are you going to do now?
}
RichTextItem rtItem = (RichTextItem) item;
PieceJointe pieceJointe = new PieceJointe();
pieceJointe = buildPieceJointe(file, nameFichier, chemin);
rtItem.embedObject(EmbeddedObject.EMBED_ATTACHMENT, "", pieceJointe.getChemin()
+ pieceJointe.getNomPiece(), pieceJointe.getNomPiece());
monDoc.computeWithForm(true, false);
monDoc.save(true);
} catch (NotesException e) {
throw new FacesException(e);
} finally {
DominoUtil.recycle(monDoc);
}
}
Finally, apart from the monDoc, you need not recycle anything else. Actually Session would be automatically recycled and anything beneath with it (so no need to recycle db, let alone the session!, good rule is don't recycle what you didn't instantiate), but it's not bad to keep the habit of keeping an eye on what you instantiate. If it were a loop with many documents you definitively want to do that. If you also worked with many items you would want to recycle them as early as possible. Anyway, considered the scope of the code it's sufficient like this. Obviously you would call DominoUtil.recycle directly from the try block. If you have multiple objects you can recycle them at once possibly by listing them in the reverse order you set them (eg. DominoUtil.recycle(item, doc, view)).
Also, what I think you miss is the check on the item in case it's not a RichTextItem - and therefore can't be cast. I put a comment where I think you should decide what to do before proceeding. If you let it like that and let the code proceed you will have the code throw an error. Always better to catch the lower level exception and re-throw a higher one (you don't want the end user to know more than it is necessary to know). In this case I went for the simplest thing: wrapped NotesException in a FacesException.

Related

Unexpected double WHERE clause in Servicestack OrmLite

We have an issue that occurs at every method call for limited periods of time. Then it works as expected. The issue is that the code produces double WHERE clauses.
We're using Servicestack 4.5.14
The method we have:
protected static void InsertOrUpdate<T>(
IDbConnection connection,
T item,
Expression<Func<T, bool>> singleItemPredicate,
Expression<Func<T, object>> updateOnlyFields = null)
{
var type = item.GetType();
var idProperty = type.GetProperty("Id");
if (idProperty == null)
{
throw new Exception("Cannot insert or update on a class with no ID property");
}
var currentId = (int)idProperty.GetValue(item);
if (currentId != 0)
{
throw new Exception("Cannot insert or update with non-zero ID");
}
var query = connection.From<T>().Where(singleItemPredicate).WithSqlFilter(WithUpdateLock);
T existingItem;
try
{
existingItem = connection.Select(query).SingleOrDefault();
Log.Verbose(connection.GetLastSql);
}
catch (SqlException)
{
Log.Verbose(connection.GetLastSql);
throw;
}
if (existingItem == null)
{
Insert(connection, item);
return;
}
var existingId = (int)idProperty.GetValue(existingItem);
idProperty.SetValue(item, existingId);
try
{
var affectedRowCount = connection.UpdateOnly(item, onlyFields: updateOnlyFields, where: singleItemPredicate);
Log.Verbose(connection.GetLastSql);
if (affectedRowCount != 1)
{
throw new SwToolsException("Update failed");
}
}
catch (SqlException)
{
Log.Verbose(connection.GetLastSql);
throw;
}
}
When it all works, an example output from the logs could be:
SELECT "Id", "Application", "Hostname", "LastContact", "Version", "ToolState", "ServerState"
FROM "ca"."ExecutionHost"
WITH (UPDLOCK) WHERE ("Hostname" = #0)
UPDATE "ca"."ExecutionHost" SET "LastContact"=#LastContact, "Version"=#Version, "ToolState"=#ToolState, "ServerState"=#ServerState WHERE ("Hostname" = #0)
When it fails, the output (same session, only seconds later) was:
SELECT "Id", "Application", "Hostname", "LastContact", "Version", "ToolState", "ServerState"
FROM "ca"."ExecutionHost"
WITH (UPDLOCK) WHERE ("Hostname" = #0)
UPDATE "ca"."ExecutionHost" SET "LastContact"=#LastContact, "Version"=#Version, "ToolState"=#ToolState, "ServerState"=#ServerState WHERE "LastContact"=#LastContact, "Version"=#Version, "ToolState"=#ToolState, "ServerState"=#ServerState WHERE ("Hostname" = #0)
Marked in bold is the addition to the SQL that makes the call to fail. It seems that it adds an additional WHERE clause with the content from the SET clause.
We've been debugging this for a while and don't really know if the issue is on "our" side or in Servicestack.
Any ideas on where to continue?

Accidently deleting entire linked list when trying to delete the head

I'm working on a checker's simulation game for my C++ class. My issue is with the linked list that holds the checkers. I can delete any checker perfectly with the exception of the head of the list. I've looked around here and other websites and I believe there's a memory leak somewhere. I'm fairly new to C++ so I'm not sure what to really do other than playing around with things (which will probably just create a bigger problem). I've never posted here before, so excuse me if the formatting is slightly off or too messy. I'll try to make it brief. First, here's a snippet of the node class for the linked list.
class CheckerpieceNode
{
private:
Checkerpiece *Node;
CheckerpieceNode *Next;
public:
CheckerpieceNode(); // sets Node and Next to NULL in .cpp file
void setNode(Checkerpiece *node);
void setNext(CheckerpieceNode *next);
Checkerpiece* getNode();
CheckerpieceNode* getNext();
};
And the functions are set up pretty much as you would expect in a Checkerpiece.cpp class.
Here's how the code is used. Its called by a Checkerboard object in my main class.
theCheckerboard.removeChecker(theCheckerboard.findChecker(selector->getCurrentX() + 0, selector->getCurrentY() - VERTICAL_SHIFT, listHead), listHead);
The VERTICAL_SHIFT simply has to do with the way my checkerboard graphic is on the console. Since it works perfectly for all other nodes (excluding the head) I've ruled it out as a source of error. Selector is a checkerpiece object but its not part of the list.
Here's the actual findChecker and removeChecker code from Checkerboard class.
Checkerpiece* findChecker(int x, int y, CheckerpieceNode* list_head)
{
if(list_head== NULL) return NULL; // do nothing
else
{
CheckerpieceNode* node = new CheckerpieceNode;
node = list_head;
while(node != NULL && node->getNode() != NULL)
{
if()// comparison check here, but removed for space
{
return node->getNode();
delete node;
node = NULL;
}
else // traversing
node = node->getNext();
}
return NULL;
}
}
void removeChecker(Checkerpiece* d_checker, CheckerpieceNode* list_head)
{
if(list_head== NULL) // throw exception
else
{
CheckerpieceNode *temp = NULL, *previous = NULL;
Checkerpiece* c_checker= new Checkerpiece;
temp = list_head;
while(temp != NULL && temp->getNode() != NULL)
{
c_checker= temp->getNode();
if(d_checker!= c_checker)
{
previous = temp;
temp = temp->getNext();
}
else
{
if(temp != list_head)
{
previous->setNext(temp->getNext());
delete temp;
temp = NULL;
}
else if(temp == list_head) // this is where head should get deleted
{
temp = list_head;
list_head= list_head->getNext();
delete temp;
temp = NULL;
}
return;
}
}
}
}
Oh my, you're complicating it. Lots of redundant checks, assignments and unnecessary variables (like c_checker which leaks memory too).
// Write down the various scenarios you can expect first:
// (a) null inputs
// (b) can't find d_checker
// (c) d_checker is in head
// (d) d_checker is elsewhere in the list
void removeChecker(Checkerpiece* d_checker, CheckerpieceNode* list_head) {
// first sanitize your inputs
if (d_checker == nullptr || list_head == nullptr) // use nullptr instead of NULL. its a keyword literal of type nullptr_t
throw exception;
// You understand that there is a special case for deleting head. Good.
// Just take care of it once and for all so that you don't check every time in the loop.
CheckerpieceNode *curr = list_head;
// take care of deleting head before traversal
if (d_checker == curr->getNode()) {
list_head = list_head->next; // update list head
delete curr; // delete previous head
return; // we're done
}
CheckerpieceNode *prev = curr;
curr = curr->next;
// traverse through the list - keep track of previous
while (curr != nullptr) {
if (d_checker == curr->getNode()) {
prev->next = curr->next;
delete curr;
break; // we're done!
}
prev = curr;
curr = curr->next;
}
}
I hope that helps. Take the time to break down the problem into smaller pieces, figure out the scenarios possible, how you'll handle them and only then start writing code.
Based on this edit by the question author, the solution he used was to:
I modified the code to show the address passing in the checker delete
function.
void delete_checker(Checker* d_checker, CheckerNode* &list_head) // pass by address
{
if(list_head== NULL) // throw exception
else
{
CheckerNode*temp = NULL, *previous = NULL;
Checker* c_checker= new Checker;
temp = list_head;
while(temp != NULL && temp->node!= NULL)
{
c_checker= temp->node;
if(d_checker!= c_checker)
{
previous = temp;
temp = temp->next;
}
else
{
if(temp != list_head)
{
previous->next = temp->next;
delete temp;
temp = NULL;
}
else if(temp == list_head) // this is where head should get deleted
{
temp = list_head;
list_head= list_head->next;
delete temp;
temp = NULL;
}
delete c_checker;
c_checker = nullptr;
return;
}
}
}
}
removeChecker cannot modify the value of list_head as it is past by value. The method signature should be:
void removeChecker(Checkerpiece* d_checker, CheckerpieceNode** list_head)
// You will need to call this function with &list_head
or
void removeChecker(Checkerpiece* d_checker, CheckerpieceNode* &list_head)
// Calling code does not need to change

CRM 2011 development: Get the following error if I try to get related entity: Object reference not set to an instance of an object

I try to get a related entity and get this error: Object reference not set to an instance of an object.
See below my code:
public IEnumerable<RUBAnnotation> GetAnnotationsByServiceRequestId(string serviceRequestId)
{
List<Annotation> annotationList = new List<Annotation>();
try
{
using (OrganizationServiceProxy organizationProxy = new OrganizationServiceProxy(organisationWebServiceUri, null, userCredentials, deviceCredentials))
{
organizationProxy.EnableProxyTypes();
var service = (IOrganizationService)organizationProxy;
OrganizationServiceContext orgContext = new OrganizationServiceContext(service);
Relationship rel = new Relationship("Incident_Annotation");
// get all incidents by incidentId
IEnumerable<Incident> incidents = from c in orgContext.CreateQuery<Incident>()
where c.Id == new Guid(serviceRequestId)
select c;
return GetAnnotationsEntities(incidents);
}
}
catch (Exception)
{
throw;
}
return null;
}
private List<RUBAnnotation> GetAnnotationsEntities(IEnumerable<Incident> incidents)
{
List<RUBAnnotation> annotationsList = new List<RUBAnnotation>();
try
{
foreach (Incident incident in incidents)
{
foreach (var annotation in incident.Incident_Annotation) // HERE OCCURS THE EXCEPTION!!
{
if (!string.IsNullOrEmpty(annotation.NoteText))
{
var customAnnotation = new RUBAnnotation();
customAnnotation.Id = annotation.Id.ToString();
if (annotation.Incident_Annotation != null)
{
customAnnotation.ServiceRequestId = annotation.Incident_Annotation.Id.ToString();
}
customAnnotation.Message = annotation.NoteText;
customAnnotation.CreatedOn = (DateTime)annotation.CreatedOn;
customAnnotation.UserId = annotation.CreatedBy.Id.ToString();
annotationsList.Add(customAnnotation);
}
}
}
}
catch (Exception e)
{
throw e;
}
return annotationsList;
}
Why do I get this error when I try to get incident.Incident_Annotation ? I think incident.Incident_Annotation is NULL, but why? Al my incidents have minimal 1 or more annotations.
Related entities must be explicitly loaded, you can find more information on this MSDN article:
MSDN - Access Entity Relationships

XmlSchemaInfo.SchemaElement is null after validation with reciving PVSI

I try to validate XDocument with compiled (and correct) schema set and with providing post validation schema info (PVSI):
public void ValidateDoc(XDocument doc)
{
if (doc == null)
return;
// _schema is correct filled schema-set
if (!_schemas.IsCompiled)
_schemas.Compile();
try
{
_validated.Clear();
if (_schemas.Count > 0)
doc.Validate(_schemas, OnValidate, true);
foreach (var item in _validated)
{
var si = item.GetSchemaInfo();
// si exists and si.Validity is set to XmlSchemaValidity.Invalid but si.SchemaElement and si.SchemaAttribute is null
}
}
catch (XmlSchemaException err)
{
_log.FatalException(string.Format("Failed to validate document {0} [{1}, {2}] ", doc.BaseUri, err.LineNumber, err.LinePosition), err);
}
}
protected virtual void OnValidate(object sender, ValidationEventArgs args)
{
if (ValidationEvent != null)
ValidationEvent(sender, args);
var xobj = sender as XObject;
if (xobj != null)
{
xobj.AddAnnotation(new XmlErrInfo(args));
if (xobj is XElement)
_validated.Add((XElement)xobj);
}
}
But .GetSchemaInfo().SchemaElement is null (and other fields its empty too), instead of point to compiled schema element (I need to use it in future validation scenarios of same elements). What's wrong with it or what I doing wrong?
Well if you wanted to access the SchemaElement of valid elements I could understand your approach but you seem to want to access the SchemaElement of those invalid elements reported to the event handler. I don't think those properties are populated for invalid nodes.

File connection+j2me

I want to make the application where I can get all the images no matter whether it is in phone or in external memory. I want to import all that images in my application. How can it be possible? I came to know that it is possible through file connection. But not getting exact idea.
Get all the file system roots using FileSystemRegistry.listRoots()
Open connection to each root in turn using FileConnection fconn = (FileConnection)Connector.open(root)
List the folder using fconn.list().
For each entry in the list, if it ends with an image extension (file.getName().endsWith(".png") etc), then it's an image.
If the entry is a folder (file.isDirectory() returns true) then use fconn.setFileConnection(folder) to traverse into that directory/
Do the same recursively for all folders in all roots.
Here is a code snippet I once used for my application. It more or less does the same in funkybros steps.
protected void showFiles() {
if (path == null) {
Enumeration e = FileSystemRegistry.listRoots();
path = DATAHEAD; //DATAHEAD = file:///
setTitle(path);
while (e.hasMoreElements()) {
String root = (String) e.nextElement();
append(root, null);
}
myForm.getDisplay().setCurrent(this);
} else {
//this if-else just sets the title of the Listing Form
if (selectedItem != null) {
setTitle(path + selectedItem);
}
else {
setTitle(path);
}
try {
// works when users opens a directory, creates a connection to that directory
if (selectedItem != null) {
fileConncetion = (FileConnection) Connector.open(path + selectedItem, Connector.READ);
} else // works when presses 'Back' to go one level above/up
{
fileConncetion = (FileConnection) Connector.open(path, Connector.READ);
}
// Check if the selected item is a directory
if (fileConncetion.isDirectory()) {
if (selectedItem != null) {
path = path + selectedItem;
selectedItem = null;
}
//gathers the directory elements
Enumeration files = fileConncetion.list();
while (files.hasMoreElements()) {
String file = (String) files.nextElement();
append(file, null);
}
//
myForm.getDisplay().setCurrent(this);
try {
if (fileConncetion != null) {
fileConncetion.close();
fileConncetion = null;
}
} catch (IOException ex) {
ex.printStackTrace();
}
}//if (fileConncetion.isDirectory())
else {
System.out.println(path);
//if it gets a file then calls the publishToServer() method
myForm.publishToServer();
}

Resources