Docx4j: PPTX got corrupted while inserting an ellipse object - java

i have been searching the whole day for a solution but i'm unable to find one. That's why i decided to ask a question.
My problem is that i'm inserting a ellipse object to the PPTX file. When i tries to open the presentation MS OFfice says it's corrupted and tries to repair. It ends up deleting the slide and presents the master slide.
See below my code:
the function officeXReport.getTemplatename() contains the filename of the PPTX (e.g. *Status_Report_template.pptx*)
The template pptx file contains only 1 slide.
The function officeXReport.getNewfilename() contains the new filename of the PPTX (e.g. *Status_Report_2014-03-16.pptx*)
try {
PresentationMLPackage presentationMLPackage = (PresentationMLPackage)OpcPackage.load(new java.io.File(officeXReport.getTemplatename()));
MainPresentationPart pp = presentationMLPackage.getMainPresentationPart();
boolean noLine = false;
STShapeType st = STShapeType.ELLIPSE;
int i = 1;
SlidePart slidePart = (SlidePart)presentationMLPackage.getParts().getParts().get(pp.getSlide(0).getPartName());
Shape sample = ((Shape)XmlUtils.unmarshalString(
getPresetShape(st.value(), noLine, Long.toString(1839580), Long.toString(1314971), Long.toString(184337), Long.toString(184338), "92D050"), Context.jcPML) );
slidePart.getJaxbElement().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame().add(sample);
presentationMLPackage.save(new java.io.File(officeXReport.getNewfilename()));
} catch (Exception ex) {
System.out.println("Exception thrown = " + ex.getMessage());
return null;
}
The related function getPresetShape():
private static String getPresetShape(String preset, boolean noLine, String x, String y, String cx, String cy, String colorcode) {
String txBody = "";
String ln = "";
String style = "";
if (!noLine) {
ln = "<a:ln w=\"3175\">"
+"<a:solidFill>"
+"<a:srgbClr val=\"000000\"/>"
+"</a:solidFill>"
+"</a:ln>";
style = "<p:style>\n" +
"<a:lnRef idx=\"1\">\n" +
"<a:schemeClr val=\"accent1\"/>\n" +
"</a:lnRef>\n" +
"<a:fillRef idx=\"3\">\n" +
"<a:schemeClr val=\"accent1\"/>\n" +
"</a:fillRef>\n" +
"<a:effectRef idx=\"2\">\n" +
"<a:schemeClr val=\"accent1\"/>\n" +
"</a:effectRef>\n" +
"<a:fontRef idx=\"minor\">\n" +
"<a:schemeClr val=\"lt1\"/>\n" +
"</a:fontRef>\n" +
"</p:style>";
txBody = "<p:txBody>\n" +
"<a:bodyPr rtlCol=\"false\" anchor=\"ctr\"/>\n" +
"<a:lstStyle/>\n" +
"<a:p>\n" +
"<a:pPr algn=\"ctr\"/>\n" +
"<a:endParaRPr lang=\"en-US\" sz=\"1100\" u=\"sng\" dirty=\"false\">\n" +
"<a:latin typeface=\"Futura Com Light\" panose=\"020B0402020204020303\" pitchFamily=\"34\" charset=\"0\"/>\n" +
"</a:endParaRPr>\n" +
"</a:p>\n" +
"</p:txBody>";
}
return
"<p:sp xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\">"
+ "<p:nvSpPr>"
+ "<p:cNvPr id=\"32\" name=\"Ellipse 2\" />"
+ "<p:cNvSpPr/>"
+ "<p:nvPr/>"
+ "</p:nvSpPr>"
+ "<p:spPr>"
+ "<a:xfrm>"
+ "<a:off x=\"" + x + "\" y=\"" + y + "\"/>"
+ "<a:ext cx=\"" + cx + "\" cy=\""+ cy + "\"/>"
+ "</a:xfrm>"
+ "<a:prstGeom prst=\"" + preset + "\">"
+ "<a:avLst/>"
+ "</a:prstGeom>"
+ "<a:solidFill>"
+ "<a:srgbClr val=\""+ colorcode + "\"/>"
+ "</a:solidFill>"
+ ln
+ "</p:spPr>"
+ style
+ txBody
+ "</p:sp>";
}
I have looked into the slide1.xml file which is missing the XML header compared to a correct slide1.xml file :
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
How can i get the xml header definition into the slide1.xml ?
Thanks,
Asad

Related

Netsuite getting error while generating signature with filter

I am trying to create a RestAPI request to fetch details of a records with a filter 'START_WITH'. But every request I send is getting rejected with the error '401 Unauthorized. Invalid Signature'. But if I don't add the filter and only send the normal request, It gives correct response back.
My code for generating signature is:
public String generateOauthHeader(
String method, UserFields userFields, String baseUrl, String offset, String limit) {
long timestamp = new Date().getTime() / 1000;
String nonce = getAlphaNumericString();
ArrayList<String> parameters = new ArrayList<>();
parameters.add(
ApplicationConstants.CONSUMER_KEY
+ ApplicationConstants.EQUAL
+ userFields.getConsumerKey());
parameters.add(ApplicationConstants.NONCE + ApplicationConstants.EQUAL + nonce);
parameters.add(
ApplicationConstants.SIGNATURE_METHOD_KEY
+ ApplicationConstants.EQUAL
+ ApplicationConstants.SIGNATURE_METHOD_VAL);
parameters.add(ApplicationConstants.TIMESTAMP + ApplicationConstants.EQUAL + timestamp);
parameters.add(
ApplicationConstants.OAUTH_TOKEN + ApplicationConstants.EQUAL + userFields.getTokenId());
parameters.add(
ApplicationConstants.VERSION_KEY
+ ApplicationConstants.EQUAL
+ ApplicationConstants.VERSION_VAL);
if (offset != null) {
parameters.add(ApplicationConstants.OFFSET + ApplicationConstants.EQUAL + offset);
}
if (limit != null) {
parameters.add(ApplicationConstants.LIMIT_CLAUSE + ApplicationConstants.EQUAL + limit);
}
parameters.add("q" + ApplicationConstants.EQUAL + "companyname START_WITH COMP1234");
Collections.sort(parameters);
StringBuffer parametersList = new StringBuffer();
for (int i = 0; i < parameters.size(); i++) {
parametersList.append(((i > 0) ? ApplicationConstants.AMPERSAND : "") + parameters.get(i));
}
String signature = null;
try {
String signatureString =
method
+ ApplicationConstants.AMPERSAND
+ URLEncoder.encode(baseUrl, StandardCharsets.UTF_8)
+ ApplicationConstants.AMPERSAND
+ URLEncoder.encode(parametersList.toString(), StandardCharsets.UTF_8);
SecretKeySpec signingKey =
new SecretKeySpec(
(userFields.getConsumerSecret()
+ ApplicationConstants.AMPERSAND
+ userFields.getTokenSecret())
.getBytes(),
ApplicationConstants.HMACSHA256);
Mac m = Mac.getInstance(ApplicationConstants.HMACSHA256);
m.init(signingKey);
m.update(signatureString.getBytes());
byte[] res = m.doFinal();
signature = Base64Coder.encodeLines(res);
} catch (Exception e) {
e.printStackTrace();
}
return ApplicationConstants.OAUTH
+ ApplicationConstants.REALM
+ ApplicationConstants.EQUAL_START_QUOTES
+ userFields.getAccountId()
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.CONSUMER_KEY
+ ApplicationConstants.EQUAL_START_QUOTES
+ userFields.getConsumerKey()
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.OAUTH_TOKEN
+ ApplicationConstants.EQUAL_START_QUOTES
+ userFields.getTokenId()
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.SIGNATURE_METHOD_KEY
+ ApplicationConstants.EQUAL_START_QUOTES
+ ApplicationConstants.SIGNATURE_METHOD_VAL
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.TIMESTAMP
+ ApplicationConstants.EQUAL_START_QUOTES
+ timestamp
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.NONCE
+ ApplicationConstants.EQUAL_START_QUOTES
+ nonce
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.VERSION_KEY
+ ApplicationConstants.EQUAL_START_QUOTES
+ ApplicationConstants.VERSION_VAL
+ ApplicationConstants.END_QUOTES
+ ApplicationConstants.SIGNATURE
+ ApplicationConstants.EQUAL_START_QUOTES
+ URLEncoder.encode(signature, StandardCharsets.UTF_8)
+ ApplicationConstants.QUOTES;
}
Url generated without filter: https ://1212112-sb1.suitetalk.api.netsuite.com/services/rest/record/v1/customer/
Url generated with filter: https ://1212112-sb1.suitetalk.api.netsuite.com/services/rest/record/v1/customer?q="companyName START_WITH COMP1234"

How to add folder to zip

I have my GWT project and I want to upload files to server. I want the following algorithm to work
1) create a folder with the name from "userNumber"
2) write uploaded files to this folder
3) add folder to zip
4) delete folder (if exists)
As I write on the server side I think it is just java problem. Here is my code. I can perform only the first and the second steps, i.e. I can create a folder and write files to this folder.
#Override
public String executeAction(HttpServletRequest request,
List<FileItem> sessionFiles) throws UploadActionException {
String response = "";
userNumber = request.getParameter("userNumber");
File f = new File(ConfAppServer.getRealContextPath() + "/edoc/"
+ userNumber);
if (f.mkdir()) {
System.out.println("Directory Created");
} else {
System.out.println("Directory is not created");
}
for (FileItem item : sessionFiles) {
if (false == item.isFormField()) {
try {
String extension = item.getName().substring(
item.getName().length() - 3);
File file = null;
file = new File(ConfAppServer.getRealContextPath()
+ "/edoc/"
+ userNumber
+ System.getProperty("file.separator")
+ item.getName().substring(0,
item.getName().length() - 4) + "."
+ extension);
item.write(file);
receivedFiles.put(item.getFieldName(), file);
receivedContentTypes.put(item.getFieldName(),
item.getContentType());
response += "<file-" + cont + "-field>"
+ item.getFieldName() + "</file-" + cont
+ "-field>\n";
response += "<file-" + cont + "-name>" + item.getName()
+ "</file-" + cont + "-name>\n";
response += "<file-" + cont + "-size>" + item.getSize()
+ "</file-" + cont + "-size>\n";
response += "<file-" + cont + "-type>"
+ item.getContentType() + "</file-" + cont
+ "type>\n";
} catch (Exception e) {
throw new UploadActionException(e);
}
}
}
ZipUtils appZip = new ZipUtils(userNumber + ".zip",
ConfAppServer.getRealContextPath() + "/edoc/" + userNumber);
appZip.generateFileList(new File(ConfAppServer.getRealContextPath()
+ "/edoc/" + userNumber));
appZip.zipIt(userNumber + ".zip");
f.delete();
removeSessionFileItems(request);
return "<response>\n" + response + "</response>\n";
}
Here you can find my ZipUtils class.
When I try to delete my folder, nothing happens. The delete() method doesn't work. Help me please!!
My question is how to add folder to zip and then delete this folder.
Use java.nio.file. You won't have the hassle of manipulating the ZIP API yourself:
final Path pathToZip = Paths.get("path", "to", "your", "zip");
final URI uri = URI.create("jar:" + pathToZip.toUri());
final Map<String, ?> env = Collections.singletonMap("create", "true");
try (
final FileSystem fs = FileSystems.getFileSystem(uri, env);
) {
// write files into the zip here.
// See javadoc for java.nio.file.Files and FileSystem.getPath()
}
More details on how to use the API here.

Java renameTo() leaving cifs* files on samba mount

I have a linux java program that is reading and writing to a CIFS mounted Windows file share. See code snippet at bottom.
After execution, there are files named "cifs*" left in the directory. If the target directory is on the local file system, the code works like a champ. However, if the target directory is a CIFS mounted Windows file share, I get the left-over files. I'm not sure what configuration changes I need to make to fix. Any help is greatly appreciated.
FileRenameMutex myFileRenameMutex = new FileRenameMutex("/WindowsMount/MoveLock");
class FileRenameMutex
{
// global variables
String lockFileBasename;
String unusedExtension = "_Unused";
String unusedFilename;
String inUseFilename;
String localMachineAddress;
String formattedTime;
// log4j logger for this class
public static Logger logMutex = Logger.getLogger(FileRenameMutex.class.getName());
public FileRenameMutex(String _lockFileBase) {
this.lockFileBasename = _lockFileBase;
logMutex.debug("FileRenameMutex: Constructor, with file " + lockFileBasename + " user = " + System.getProperty("user.name"));
try {
localMachineAddress = InetAddress.getLocalHost().getHostAddress();
//localMachineAddress = InetAddress.getLocalHost().getHostName();
} catch ( Exception e ) {
localMachineAddress = "UNKNOWN_HOST";
logMutex.error(" Could not determine host address. " + e.getMessage());
}
// set the file names
unusedFilename = lockFileBasename + unusedExtension;
inUseFilename = lockFileBasename + "_" + localMachineAddress;
logMutex.debug(" Local machine = " + localMachineAddress);
logMutex.debug(" Unused file name = " + this.unusedFilename);
logMutex.debug(" In Use file name = " + this.inUseFilename);
}
public boolean tryAcquire() throws InterruptedException {
boolean returnVal = false;
File unusedFile = new File(unusedFilename);
File inUseFile = new File(inUseFilename);
formattedTime = new Date().toString();
String inUseText = "This file created by the Alfresco cron job to MoveFileAndCreateDir "
+ "(move files from Unfiled to Filed folders).\n"
+ "Running on " + localMachineAddress + "\n Started at " + formattedTime + "\n";
try {
FileWriter fstream = new FileWriter(inUseFile);
BufferedWriter out = new BufferedWriter(fstream);
// attempt to rename file
logMutex.debug(" Attempting to rename mutex file " + unusedFilename + " to " + inUseFilename);
if ( unusedFile.renameTo(inUseFile) ) {
logMutex.debug(" Rename to inUse successful");
out.write(inUseText);
out.flush();
out.close();
returnVal = true; // lock was acquired
} else {
// System.out.println("Rename to inUse failed");
logMutex.error(" Rename of " + unusedFilename + " to " + inUseFilename + " failed in tryAcquire().");
}
} catch ( Exception e ) {
throw new InterruptedException("Error acquiring lock in tryAcquire(): " + e.getMessage());
}
return returnVal;
}
public void release() {
File unusedFile = new File(unusedFilename);
File inUseFile = new File(inUseFilename);
String unusedText = "This file was last by the Alfresco cron job to MoveFileAndCreateDir "
+ "Ran on " + localMachineAddress + "\n Started at " + formattedTime + "\n";
try {
FileWriter fstream = new FileWriter(inUseFile);
BufferedWriter out = new BufferedWriter(fstream);
out.write(unusedText);
out.flush();
out.close();
// attempt to rename file
logMutex.debug(" Attempting to rename active mutex file " + inUseFilename + " back to " + unusedFilename);
if ( inUseFile.renameTo(unusedFile) ) {
logMutex.debug(" Rename back to unused successful");
} else {
logMutex.error(" Rename of " + inUseFilename + " to " + unusedFilename + " failed in release().");
}
} catch ( Exception e ) {
logMutex.error("Error resetting lock file in release(): " + e.getMessage());
}
} // release()
} // end of class FileRenameMutex

How to generate a PNG image from a dot file format with Graphviz

I have a java class that implements a priority queue. Then I have a class test that generates a graph like this:
digraph G {
Milan (0.0) -> Turin (1.2)
Milan (0.0) -> Montreal (7.0)
Turin (1.2) -> Paris (5.8)
Turin (1.2) -> Tokyo (2.2)
}
This graph is saved in a file called "queue".
Now I wish that this graph was displayed in a PNG image using Graphviz.
So the last call of my test files (after you have created and filled the queue with priority) is:
queue.toString("queue");
All right. The toString method is the following:
public void toString(String fileDot){
try {
FileOutputStream file = new FileOutputStream(fileDot);
PrintStream Output = new PrintStream(file);
Output.print(this.printQueue());
Output.close();
File f = new File(fileDot);
String arg1 = f.getAbsolutePath();
String arg2 = arg1 + ".png";
String[] c = {"dot", "-Tpng", arg1, "-o", arg2};
Process p = Runtime.getRuntime().exec(c);
int err = p.waitFor();
}
catch(IOException e1) {
System.out.println(e1);
}
catch(InterruptedException e2) {
System.out.println(e2);
}
}
private String printQueue() throws IOException {
String g = new String("");
char c = '"';
g = g.concat("digraph G {\n");
if(isEmpty())
g = g.concat(" " + "Empty priority queue.");
else {
for(int i = 0; i < lastIndex; i++) {
if(heap[2 * i] != null) {
g = g.concat("" + heap[i].elem + " (" + heap[i].prior + ") " + " " + " -> " + " " + "" + heap[i * 2].elem + " (" + heap[i * 2].prior + ") \n" );
if(heap[2 * i + 1] != null)
g = g.concat("" + heap[i].elem + " (" + heap[i].prior + ") " + " " + " -> " + " " + "" + heap[i * 2 + 1].elem + " (" + heap[i * 2 + 1].prior + ") \n" );
}
} //end for
} //end else
g = g.concat("}");
return g;
}
Why is not generated image .png? Where am I wrong?
Of course I installed Graphviz.
Thanks
When I ran the .dot file above through dot at the command line, I got:
$ dot -Tpng queue.dot -oqueue.png
Warning: queue.dot:2: syntax error in line 2 near '('
Thus, the parenthesised numbers in the node names are not valid in dot syntax. If you remove them, I expect the .png file would be created successfully. If you need the parenthesised numbers in your output, I suggest looking up node labels in the GraphViz documentation.
I'd also note that toString() does not seem like a particularly clear name for a function that creates a .png file so changing the name of the function might be advisable.
Try using dot's -O option instead of -o. According to dot -? here's what it does:
Automatically generate an output filename based on the input filename with a .'format' appended. (Causes all -ofile options to be ignored.)
So you could change
String[] c = {"dot", "-Tpng", arg1, "-o", arg2};
to
String[] c = {"dot", "-Tpng", arg1, "-O"};

Jsoup: How to get all html between 2 header tags

I am trying to get all html between 2 h1 tags. Actual task is to break the html into frames(chapters) based of the h1(heading 1) tags.
Appreciate any help.
Thanks
Sunil
If you want to get and process all elements between two consecutive h1 tags you can work on siblings. Here's some example code:
public static void h1s() {
String html = "<html>" +
"<head></head>" +
"<body>" +
" <h1>title 1</h1>" +
" <p>hello 1</p>" +
" <table>" +
" <tr>" +
" <td>hello</td>" +
" <td>world</td>" +
" <td>1</td>" +
" </tr>" +
" </table>" +
" <h1>title 2</h1>" +
" <p>hello 2</p>" +
" <table>" +
" <tr>" +
" <td>hello</td>" +
" <td>world</td>" +
" <td>2</td>" +
" </tr>" +
" </table>" +
" <h1>title 3</h1>" +
" <p>hello 3</p>" +
" <table>" +
" <tr>" +
" <td>hello</td>" +
" <td>world</td>" +
" <td>3</td>" +
" </tr>" +
" </table>" +
"</body>" +
"</html>";
Document doc = Jsoup.parse(html);
Element firstH1 = doc.select("h1").first();
Elements siblings = firstH1.siblingElements();
List<Element> elementsBetween = new ArrayList<Element>();
for (int i = 1; i < siblings.size(); i++) {
Element sibling = siblings.get(i);
if (! "h1".equals(sibling.tagName()))
elementsBetween.add(sibling);
else {
processElementsBetween(elementsBetween);
elementsBetween.clear();
}
}
if (! elementsBetween.isEmpty())
processElementsBetween(elementsBetween);
}
private static void processElementsBetween(
List<Element> elementsBetween) {
System.out.println("---");
for (Element element : elementsBetween) {
System.out.println(element);
}
}
I don't know Jsoup that good, but a straight forward approach could look like this:
public class Test {
public static void main(String[] args){
Document document = Jsoup.parse("<html><body>" +
"<h1>First</h1><p>text text text</p>" +
"<h1>Second</h1>more text" +
"</body></html>");
List<List<Node>> articles = new ArrayList<List<Node>>();
List<Node> currentArticle = null;
for(Node node : document.getElementsByTag("body").get(0).childNodes()){
if(node.outerHtml().startsWith("<h1>")){
currentArticle = new ArrayList<Node>();
articles.add(currentArticle);
}
currentArticle.add(node);
}
for(List<Node> article : articles){
for(Node node : article){
System.out.println(node);
}
System.out.println("------- new page ---------");
}
}
}
Do you know the structure of the articles and is it always the same? What do you want to do with the articles? Have you considered splitting them on the client side? This would be an easy jQuery Job.
Iterating over the elements between consecutive <h> elements seems to be fine, except one thing. Text not belonging to any tag, like in <h1/>this<h1/>. To workaround this I implemented splitElemText function to get this text. First split whole parent element using this method. Then except the element, process the suitable entry from the splitted text. Remove calls to htmlToText if you want raw html.
/** Splits the text of the element <code>elem</code> by the children
* tags.
* #return An array of size <code>c+1</code>, where <copde>c</code>
* is the number of child elements.
* <p>Text after <code>n</code>th element is found in <code>[n+1]</code>.
*/
public static String[] splitElemText(Element elem)
{
int c = elem.children().size();
String as[] = new String[c + 1];
String sAll = elem.html();
int iBeg = 0;
int iChild = 0;
for (Element ch : elem.children()) {
String sChild = ch.outerHtml();
int iEnd = sAll.indexOf(sChild, iBeg);
if (iEnd < 0) { throw new RuntimeException("Tag " + sChild
+" not found in its parent: " + sAll);
}
as[iChild] = htmlToText(sAll.substring(iBeg, iEnd));
iBeg = iEnd + sChild.length();
iChild += 1;
}
as[iChild] = htmlToText(sAll.substring(iBeg));
assert(iChild == c);
return as;
}
public static String htmlToText(String sHtml)
{
Document doc = Jsoup.parse(sHtml);
return doc.text();
}

Categories