Okay, I've looked at quite a few stack overflow questions and quite a few blogs, and still cannot find the answer to this. No, it doesn't look like it is missing braces, has extra semicolons, or any other typo that I am aware of. Why is the 'else' showing an error?
// check if myid property is set and create it if not
String subtopicMyId = subtopicNode.hasProperty("myid") ? subtopicNode.getProperty("myid").getString() : "";
if (subtopicMyId.equals("")) {
// generate new myid and check it against the list of existing IDs until a unique one is generated
do {
// generate new myid
Object topicmyidobj = new Object();
subtopicMyId = topicmyidobj.toString().split("#")[1].toUpperCase();
} while ( subtopicMyId.equals("") || existingMyIds.contains(subtopicMyId) );
// set myid on this node
subtopicNode.setProperty("myid", subtopicMyId);
subtopicNode.setProperty("parentid", topicMyId);
subtopicNode.save();
// add new myid to list of existsing IDs so that it doesn't get reused
existingMyIds.add(subtopicMyId);
} else {
// if subtopic has myid already
// compare the parentid to the parent myid
String subtopicParentId = subtopicNode.getProperty("parentid").getString();
if (!subtopicParentId.equals(topicMyId)) {
// they don't match
String subtopicNodePath = subtopicNode.getPath();
String topicNodePath = topicNode.getPath();
// find path to topic node that has matching myid to this subtopic's parentid
// loop through parent nodes
NodeIterator reorgTopicsIter = compNode.getNodes();
while (reorgTopicsIter.hasNext()) {
// loop through parent objects to find a matching myid for parentid
Node reorgTopicNode = (Node)reorgTopicsIter.next();
// get the myid property from this node, if it exists, and compare the parentid to it
String reorgTopicMyId = reorgTopicNode.hasProperty("myid") ? reorgTopicNode.getProperty("myid").getString() : "";
if (!reorgTopicMyId.equals("")) {
// parent myid exists and is not blank
if (reorgTopicMyId.equals(subtopicParentId)) {
// parentid does match parent myid
String reorgTopicNodePath = reorgTopicNode.getPath();
// determine how many parent objects there are
int reorgTopicSubtopics = 0;
NodeIterator reorgSubtopicsIter = reorgTopicNode.getNodes();
while (reorgSubtopicsIter.hasNext()) {
Node reorgSubtopicNode = (Node)reorgSubtopicsIter.next();
reorgTopicSubtopics++;
}
// set source to this child object
String source = subtopicNode.getPath();
// set destination to matching parent object with new child object appended
String destination = reorgTopicNodePath + "/subtopic-" + (reorgTopicSubtopics + 1);
// create session for move and perform move
Session session = resourceResolver.adaptTo(Session.class);
session.move(source, destination);
session.save();
} else {
// parentid does not match parent myid.
// nothing we need to do here;
// it just moves on to check next parent myid.
}
} else {
// parent myid does not exist or is blank
}
} else {
// no more parent objects to loop through, so we need to check if a match was found
// if no match was found, then parent was deleted or no longer exists, so we need to remove this child
}
} else {
// parentid does match parent myid
}
}
Here is the error in the console:
An error occurred at line: 145 in the jsp file: /apps/covidien/components/content/utilities/faq-node-process/faq-node-process.jsp
Syntax error on token "else", delete this token
142: subtopicNode.save();
143: // add new myid to list of existsing IDs so that it doesn't get reused
144: existingMyIds.add(subtopicMyId);
145: } else {
146: // if subtopic has myid already
147: // compare the parentid to the parent myid
148: String subtopicParentId = subtopicNode.getProperty("parentid").getString();
the number of if and else statement is not same. you have 4 if blocks but 5 else block.
five else with four if, not match.
At least number of if should more than else.
else can't be used after while. There's nothing in that else block anyway, so it should just be deleted.
There's a lot of redundant code here. My rewrite:
// check if myid property is set and create it if not
String subtopicMyId = subtopicNode.getProperty("myid").getString();
if (subtopicMyId == null) {
// generate new myid and check it against the list of existing IDs until a unique one is generated
do {
// generate new myid
Object topicmyidobj = new Object();
subtopicMyId = topicmyidobj.toString().split("#")[1].toUpperCase();
} while ( subtopicMyId.equals("") || existingMyIds.contains(subtopicMyId) );
// set myid on this node
subtopicNode.setProperty("myid", subtopicMyId);
subtopicNode.setProperty("parentid", topicMyId);
subtopicNode.save();
// add new myid to list of existsing IDs so that it doesn't get reused
existingMyIds.add(subtopicMyId);
} else {
// if subtopic has myid already
// compare the parentid to the parent myid
String subtopicParentId = subtopicNode.getProperty("parentid").getString();
if (!subtopicParentId.equals(topicMyId)) {
// they don't match
String subtopicNodePath = subtopicNode.getPath();
String topicNodePath = topicNode.getPath();
// find path to topic node that has matching myid to this subtopic's parentid
// loop through parent nodes
NodeIterator reorgTopicsIter = compNode.getNodes();
while (reorgTopicsIter.hasNext()) {
// loop through parent objects to find a matching myid for parentid
Node reorgTopicNode = (Node)reorgTopicsIter.next();
// get the myid property from this node, if it exists, and compare the parentid to it
String reorgTopicMyId = reorgTopicNode.getProperty("myid").getString();
if (reorgTopicMyId != null && reorgTopicMyId.equals(subtopicParentId)) {
// parentid does match parent myid
String reorgTopicNodePath = reorgTopicNode.getPath();
// determine how many parent objects there are
int reorgTopicSubtopics = 0;
NodeIterator reorgSubtopicsIter = reorgTopicNode.getNodes();
while (reorgSubtopicsIter.hasNext()) {
Node reorgSubtopicNode = (Node)reorgSubtopicsIter.next();
reorgTopicSubtopics++;
}
// set source to this child object
String source = subtopicNode.getPath();
// set destination to matching parent object with new child object appended
String destination = reorgTopicNodePath + "/subtopic-" + (reorgTopicSubtopics + 1);
// create session for move and perform move
Session session = resourceResolver.adaptTo(Session.class);
session.move(source, destination);
session.save();
} else {
// parentid does not match parent myid.
// nothing we need to do here;
// it just moves on to check next parent myid.
}
}
} else {
// parentid does match parent myid
}
}
Related
I'm trying to retrieve the latest mail received in my mail box from one sender. I have an issue when a sender reply on one of his emails, for example:
screenshot of my exemple
I want to get the last message received on 04/28 instead of getting the two messages.
In my code, I simply did this to get my messages:
defaultFolder = store.getDefaultFolder().getFolder("inbox");
Message [] msg = defaultFolder.getMessages();
Any ideas of how we can get only the latest email of the same sender ?
Thank you!
To get the latest recieved email from the folder you can Sort items by using the Items.Sort method, here is a VBA sample (the Outlook object model is common for all kind of applications):
Sub SortByDueDate()
Dim myNameSpace As Outlook.NameSpace
Dim myFolder As Outlook.Folder
Dim myItem As Outlook.TaskItem
Dim myItems As Outlook.Items
Set myNameSpace = Application.GetNamespace("MAPI")
Set myFolder = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myFolder.Items
myItems.Sort "[ReceivedTime]", False
For Each myItem In myItems
MsgBox myItem.Subject & "-- " & myItem.DueDate
Next myItem
End Sub
So, the first item will be the latest received. As soon as you got the latest item you can iterate over all items in the same conversation. The MailItem.GetConversation method obtains a Conversation object that represents the conversation to which this item belongs. So, you may get all items from the conversation. Read more about that in the Obtain and Enumerate Selected Conversations article. For example:
void DemoConversation()
{
object selectedItem =
Application.ActiveExplorer().Selection[1];
// This example uses only
// MailItem. Other item types such as
// MeetingItem and PostItem can participate
// in the conversation.
if (selectedItem is Outlook.MailItem)
{
// Cast selectedItem to MailItem.
Outlook.MailItem mailItem =
selectedItem as Outlook.MailItem;
// Determine the store of the mail item.
Outlook.Folder folder = mailItem.Parent
as Outlook.Folder;
Outlook.Store store = folder.Store;
if (store.IsConversationEnabled == true)
{
// Obtain a Conversation object.
Outlook.Conversation conv =
mailItem.GetConversation();
// Check for null Conversation.
if (conv != null)
{
// Obtain Table that contains rows
// for each item in the conversation.
Outlook.Table table = conv.GetTable();
Debug.WriteLine("Conversation Items Count: " +
table.GetRowCount().ToString());
Debug.WriteLine("Conversation Items from Table:");
while (!table.EndOfTable)
{
Outlook.Row nextRow = table.GetNextRow();
Debug.WriteLine(nextRow["Subject"]
+ " Modified: "
+ nextRow["LastModificationTime"]);
}
Debug.WriteLine("Conversation Items from Root:");
// Obtain root items and enumerate the conversation.
Outlook.SimpleItems simpleItems
= conv.GetRootItems();
foreach (object item in simpleItems)
{
// In this example, only enumerate MailItem type.
// Other types such as PostItem or MeetingItem
// can appear in the conversation.
if (item is Outlook.MailItem)
{
Outlook.MailItem mail = item
as Outlook.MailItem;
Outlook.Folder inFolder =
mail.Parent as Outlook.Folder;
string msg = mail.Subject
+ " in folder " + inFolder.Name;
Debug.WriteLine(msg);
}
// Call EnumerateConversation
// to access child nodes of root items.
EnumerateConversation(item, conv);
}
}
}
}
}
void EnumerateConversation(object item,
Outlook.Conversation conversation)
{
Outlook.SimpleItems items =
conversation.GetChildren(item);
if (items.Count > 0)
{
foreach (object myItem in items)
{
// In this example, only enumerate MailItem type.
// Other types such as PostItem or MeetingItem
// can appear in the conversation.
if (myItem is Outlook.MailItem)
{
Outlook.MailItem mailItem =
myItem as Outlook.MailItem;
Outlook.Folder inFolder =
mailItem.Parent as Outlook.Folder;
string msg = mailItem.Subject
+ " in folder " + inFolder.Name;
Debug.WriteLine(msg);
}
// Continue recursion.
EnumerateConversation(myItem, conversation);
}
}
}
I'm using Milo and its example server and client. I'm adding nodes to the server but I can't figure out how to add EuInformation, i.e., unit and description. I thought about using the ExtensionObject but since EuInformation does not implement Serializable I don't know how to pass it to the ExtensionObject. I'd also like to know how I can get the namespace ID and URI on client side. So far I just set them statically as I have access to the classes.
I've implemeted the AddNodes on server side. I can add nodes, read nodes and write to nodes.
Here's what I'm doing on client side:
// Should somehow get the namespace ID and namespace dynamically.
// Maybe by iterating through all nodes??
ExpandedNodeId parentNodeId = new ExpandedNodeId(
new nodeId(2,DatatypeNamespace.NODE_IDENTIFIER),
datatypeNamespace.NAMESPACE_URI, 0);
NodeId referenceTypeId = Identifiers.String;
// Define the new node.
ExpandedNodeId requestedNewNodeId = new ExpandedNodeId(new NodeId(2, "NewNode"),
DatatypeNamespace.NAMESPACE_URI, 0);
QualifiedName browseName = new QualifiedName(2, "NewNode");
// How to get this to the server??
EUInformation euinfo = new EUInformation(null,-1,LocalizedText.english("MyUnit"),
LocalizedText.english("My Description"));
ExpandedNodeId typeDef = new ExpandedNodeId(Identifiers.BaseVariableType,
DatatypeNamespace.NAMESPACE_URI, 0);
AddNodesItem newItem = new AddNodesItem(parentNodeId, referenceTypeId,
requestedNewNodeId,rowseName,NodeClass.VariableType, null, typeDef);
List<AddNodesItem> items = new ArrayList<AddNodesItem>();
items.add(newItem);
client.addNodes(items).get();
EDIT
With the help of Kevin Herron's answer I worked something out: I adjusted the write() in my namespace class. I can now modify the display name and description of the node with the values of the EUInformation. Here's my write() method:
#Override
public void write(WriteContext context, List<WriteValue> writeValues) {
List<StatusCode> results = Lists.newArrayListWithCapacity(writeValues.size());
for (WriteValue writeValue : writeValues) {
ServerNode node = server.getNodeMap().get(writeValue.getNodeId());
if (node != null) {
// Get the type of the variant thats about to be written to the node
NodeId variantType = writeValue.getValue().getValue().getDataType().get();
if (variantType.equals(Identifiers.Structure)) {
ExtensionObject o = (ExtensionObject) writeValue.getValue().getValue().getValue();
if (o.getEncodingTypeId().equals(Identifiers.EUInformation_Encoding_DefaultBinary)) {
EUInformation euInformation = (EUInformation) o.decode();
node.setDescription(euInformation.getDescription());
node.setDisplayName(euInformation.getDisplayName());
System.out.println("Wrote EUInformation " + euInformation);
results.add(StatusCode.GOOD);
context.complete(results);
return;
}
}
try {
node.writeAttribute(new AttributeContext(context), writeValue.getAttributeId(),
writeValue.getValue(), writeValue.getIndexRange());
results.add(StatusCode.GOOD);
System.out.println(String.format("Wrote value %s to %s attribute of %s",
writeValue.getValue().getValue(),
AttributeId.from(writeValue.getAttributeId()).map(Object::toString).orElse("unknown"),
node.getNodeId()));
} catch (UaException e) {
System.out.println(String.format("Unable to write %s", writeValue.getValue()));
results.add(e.getStatusCode());
}
} else {
results.add(new StatusCode(StatusCodes.Bad_NodeIdUnknown));
}
}
context.complete(results);
}
Ok, so you would add a new VaribleNode with a TypeDefinition of Property (Identifiers.PropertyType).
Then you would write to its Value attribute so it contains the EUInformation object:
EUInformation euInformation = ...
Variant v = new Variant(ExtensionObject.encode(euInformation));
...write the value to the node you created...
In my application on users profile page, user has:
Name: XYZ
Age: ##
Address: st.XYZ
and so on...
When an element is missing (example age) other row takes its place, so I can't hardcode the xpath of elements. What I want is:
I want to (print) extract entire table data and compare with actual.
So when I ask for "Name" as key it should give cell value infront of it as value of key.
What I tried:
I was able to get text of tr tags elements keeping td fixed. But for another user when some row is missing it fails or gives wrong value.
for (int i = 2; i < 58; i++) {
String actor_name = new WebDriverWait(driver, 30).until(ExpectedConditions
.elementToBeClickable(By.xpath(first_part+i+part_two))).getText();
System.out.print("\n"+"S.no. "+(i-1)+" "+actor_name);
try {
driver.findElement(By.xpath(first_part+i+part_two)).click();
new WebDriverWait(driver, 30).until(ExpectedConditions
.elementToBeClickable(By.partialLinkText("bio"))).click();
//driver.findElement(By.partialLinkText("bio")).click();
} catch (Exception e) {
// TODO: handle exception
System.out.println("Not a link");
}
Thread.sleep(5000);
System.out.print(" "+driver.findElement(By.xpath("//*[#id='overviewTable']/tbody/tr[3]/td[2]")).getText());
driver.get("http://www.imdb.com/title/tt2310332/fullcredits?ref_=tt_cl_sm#cast");
}
Above code works fine for top 3 actors on this page but fails for 4th because that doesn't have one row missing on bio page.
On the bio page there two columns in the table one has attribute other has its value. I want to make a collection with key value pair with key as attribute (value from left column) and its value as value from right column. So that I get the freedom of fetching the values by mentioning the attribute value.
I am using JAVA to write scripts.
Can you try out with following code and provide me with any concerns if you have any...
driver.get("http://www.imdb.com/title/tt2310332/fullcredits?ref_=tt_cl_sm#cast");
String height = "";
String actorName = "";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
List<WebElement> lstUrls = driver.findElements(By
.xpath("//span[#itemprop='name']/..")); // all a tags
List<String> urls = new ArrayList<>();
for (WebElement webElement : lstUrls) {
urls.add(webElement.getAttribute("href")); // saving all hrefs attached in each a tag
}
Map<String, String> actorHeightData = new HashMap<String, String>();
for (String string : urls) {
driver.get(string);
actorName = driver.findElement(
By.xpath(".//*[#id='overview-top']/h1/span")).getText(); // Getting actor's name
driver.findElement(By.xpath("//a[text()='Biography']")).click(); // Clicking Biography
try {
height = driver.findElement(
By.xpath("//td[.='Height']/following-sibling::td"))
.getText(); // Getting height
} catch (NoSuchElementException nsee) {
height = ""; // If height not found
}
actorHeightData.put(actorName, height); // Adding to map
}
You can create class PersonData with all nullable fields you need. But with not null getters.
for example
calss PersonData{
private String name;
public getName(){
if(name == null)
return "";
return name;
}
}
and store all persons in a List.
In you page you will ask person for field and always have something in table's cell.
I am managing to parse most of the data I need except for one as it is contained within the a href tag and I am needing the number that appears after "mmsi="
Sunsail 4013
my current parser fetches all the other data I need and is below. I tried a few things out the code commented out returns unspecified occasionally for an entry. Is there any way I can add to my code below so that when the data is returned the number "235083844" returns before the name "Sunsail 4013"?
try {
File input = new File("shipMove.txt");
Document doc = Jsoup.parse(input, null);
Elements tables = doc.select("table.shipInfo");
for( Element element : tables )
{
Elements tdTags = element.select("td");
//Elements mmsi = element.select("a[href*=/showship.php?mmsi=]");
// Iterate over all 'td' tags found
for( Element td : tdTags ){
// Print it's text if not empty
final String text = td.text();
if( text.isEmpty() == false )
{
System.out.println(td.text());
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Example of data parsed and html file here
You can use attr on an Element object to retrieve a particular attribute's value
Use substring to get the required value if the String pattern is consistent
Code
// Using just your anchor html tag
String html = "Sunsail 4013";
Document doc = Jsoup.parse(html);
// Just selecting the anchor tag, for your implementation use a generic one
Element link = doc.select("a").first();
// Get the attribute value
String url = link.attr("href");
// Check for nulls here and take the substring from '=' onwards
String id = url.substring(url.indexOf('=') + 1);
System.out.println(id + " "+ link.text());
Gives,
235083844 Sunsail 4013
Modified condition in your for loop from your code:
...
for (Element td : tdTags) {
// Print it's text if not empty
final String text = td.text();
if (text.isEmpty() == false) {
if (td.getElementsByTag("a").first() != null) {
// Get the attribute value
String url = td.getElementsByTag("a").first().attr("href");
// Check for nulls here and take the substring from '=' onwards
String id = url.substring(url.indexOf('=') + 1);
System.out.println(id + " "+ td.text());
}
else {
System.out.println(td.text());
}
}
}
...
The above code would print the desired output.
If you need value of attribute, you should use attr() method.
for( Element td : tdTags ){
Elements aList = td.select("a");
for(Element a : aList){
String val = a.attr("href");
if(StringUrils.isNotBlank(val)){
String yourId = val.substring(val.indexOf("=") + 1);
}
}
The below is a class for making local folders from database entries where each folder has a name, id and parent-id.
I have put it together as best I can but do not know enough to finish it off.
I need to "just grab the folder with id 0 and start building your Files on the disk, using folder.getChildren() as a convenient way to move down the tree then just mkdirs()" as told to me in another post but I do not understand how and where to do it. Please help
public class Loop {
public static void main(String[] args) {
int PID = 0;
int RepoID = 1;
Connection con = null;
String url = "jdbc:mysql://localhost/document_manager";
String user = "root";
String password = "Pa55w0rd";
try {
con = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
Map<Integer,Folder> data = new HashMap<Integer,Folder>();
while( PID < 50 )
{
try {
Statement st = con.createStatement();
ResultSet result = st.executeQuery("SELECT name, category_id, parent_id FROM categories WHERE parent_id = '"+PID+"' AND repository_id = '"+RepoID+"'");
while (result.next ())
{
String FolderName = result.getString ("name");
String FolderId = result.getString ("category_id");
String ParentId = result.getString ("parent_id");
int intFolderId = Integer.parseInt(FolderId);
int intParentId = Integer.parseInt(ParentId);
System.out.println( FolderId+" "+FolderName+" "+ParentId );
//intFolderId = Integer.valueOf(FolderId);
//intParentId = Integer.valueOf(FolderId);
Folder newFolder = new Folder(FolderName, intFolderId, intParentId);
data.put(newFolder.getId(), newFolder);
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
PID++;
}
for(Folder folder : data.values()) {
int parentId = folder.getParentFolderId();
Folder parentFolder = data.get(parentId);
if(parentFolder != null)
parentFolder.addChildFolder(folder);
}
}
}
Basically reading hierachies from the database is not trivial, but if you read one level per query that should be doable.
What you need to do is the following:
select all folders that have no parent, those are your root folders
create the folders if they don't exist already
repeat the following until you don't get any more results from the db
select all folders whose parent id is the id of the folders read in the previous iteration (or the parents)
assign the read subfolders to their parents based on the parent id
create the read subfolders in their parents
This would allow you to use a breadth-first approach, i.e. you read one level of folders per iteration and map the children to the parents using parent_id.
As an alternative you could read the children for a single parent and iterate over the hierarchy in a depth-first manner.