Could anyone please guide me how can I create one custom JAPE file and configure it with GATE source code. I have tried with following code and getting exception like "Error while parsing the grammar :" and "Neither grammarURL or binaryGrammarURL parameters are set!"
try{
Document doc = new DocumentImpl();
String str = "This is test.";
DocumentContentImpl impl = new DocumentContentImpl(str);
doc.setContent(impl);
System.setProperty("gate.home", "C:\\Program Files\\GATE_Developer_7.1");
Gate.init();
gate.Corpus corpus = (Corpus) Factory
.createResource("gate.corpora.CorpusImpl");
File gateHome = Gate.getGateHome();
File pluginsHome = new File(gateHome, "plugins");
Gate.getCreoleRegister().registerDirectories(new File(pluginsHome, "ANNIE").toURI().toURL());
Transducer transducer = new Transducer();
transducer.setDocument(doc);
transducer.setGrammarURL(new URL("file:///D:/misc_workspace/gate-7.1-build4485-SRC/plugins/ANNIE/resources/NE/SportsCategory.jape"));
transducer.setBinaryGrammarURL(new URL("file:///D:/misc_workspace/gate-7.1-build4485-SRC/plugins/ANNIE/resources/NE/SportsCategory.jape"));
LanguageAnalyser jape = (LanguageAnalyser)Factory.createResource(
"gate.creole.Transducer", gate.Utils.featureMap(
"grammarURL", "D:/misc_workspace/gate-7.1-build4485-SRC/plugins/ANNIE/resources/NE/SportsCategory.jape",
"encoding", "UTF-8"));
You would need to load the ANNIE plugin
Gate.getCreoleRegister().registerDirectories(
new File(Gate.getPluginsHome(), "ANNIE").toURI().toURL());
and then create an instance of gate.creole.Transducer with the right parameters
LanguageAnalyser jape = (LanguageAnalyser)Factory.createResource(
"gate.creole.Transducer", gate.Utils.featureMap(
"grammarURL", new URL("file:///D:/path/to/my-grammar.jape"),
"encoding", "UTF-8")); // ensure this matches the file
But the approach we usually advocate is to get your whole pipeline assembled and configured the way you want it in GATE Developer, with whatever standard components you need plus your own grammars, then save the application state to a file. You can then reload the whole application from code using a single line
CorpusController app = (CorpusController) PersistenceManager.loadObjectFromFile(savedAppFile);
Edit: the code you've added to your question has several fundamental problems. Firstly you must call Gate.init() before you do anything else with GATE - it must be before you create your Document. And secondly you must never call the constructor of a Resource class directly - always use the Factory. Likewise you should never need to call init() directly, as this is done for you as part of Factory.createResource. For example:
// initialise GATE
Gate.setGateHome(new File("C:\\Program Files\\GATE_Developer_7.1"));
Gate.init();
// load ANNIE plugin - you must do this before you can create tokeniser
// or JAPE transducer resources.
Gate.getCreoleRegister().registerDirectories(
new File(Gate.getPluginsHome(), "ANNIE").toURI().toURL());
// Build the pipeline
SerialAnalyserController pipeline =
(SerialAnalyserController)Factory.createResource(
"gate.creole.SerialAnalyserController");
LanguageAnalyser tokeniser = (LanguageAnalyser)Factory.createResource(
"gate.creole.tokeniser.DefaultTokeniser");
LanguageAnalyser jape = (LanguageAnalyser)Factory.createResource(
"gate.creole.Transducer", gate.Utils.featureMap(
"grammarURL", new File("D:\\path\\to\\my-grammar.jape").toURI().toURL(),
"encoding", "UTF-8")); // ensure this matches the file
pipeline.add(tokeniser);
pipeline.add(jape);
// create document and corpus
Corpus corpus = Factory.newCorpus(null);
Document doc = Factory.newDocument("This is test.");
corpus.add(doc);
pipeline.setCorpus(corpus);
// run it
pipeline.execute();
// extract results
System.out.println("Found annotations of the following types: " +
doc.getAnnotations().getAllTypes());
If you haven't already I strongly recommend you work through the training course materials for at least module 5, which will show you the correct way to load a document and run processing resources over it.
Thank you Ian. These training courses material is helpful. But my problem was different and I have solved it. The following code snap is how to use custom jape file in GATE. Now my custom jape file is capable to produce new annotation.
System.setProperty("gate.home", "C:\\Program Files\\GATE_Developer_7.1");
Gate.init();
ProcessingResource token = (ProcessingResource) Factory.createResource("gate.creole.tokeniser.DefaultTokeniser",Factory.newFeatureMap());
String str = "This is a test. Myself Abhijit Nag sport";
Document doc = Factory.newDocument(str);
gate.Corpus corpus = (Corpus) Factory.createResource("gate.corpora.CorpusImpl");
corpus.add(doc);
File gateHome = Gate.getGateHome();
File pluginsHome = new File(gateHome, "plugins");
Gate.getCreoleRegister().registerDirectories(new File(pluginsHome, "ANNIE").toURI().toURL());
LanguageAnalyser jape = (LanguageAnalyser)Factory.createResource(
"gate.creole.Transducer", gate.Utils.featureMap(
"grammarURL", "file:///D:/misc_workspace/gate-7.1-build4485-SRC/plugins/ANNIE/resources/NE/SportsCategory.jape","encoding", "UTF-8"));
jape.setCorpus(corpus);
jape.setDocument(doc);
jape.execute();
pipeline = (SerialAnalyserController) Factory.createResource("gate.creole.SerialAnalyserController",
Factory.newFeatureMap(), Factory.newFeatureMap(),"ANNIE");
initAnnie();
pipeline.setCorpus(corpus);
pipeline.add(token);
pipeline.add((ProcessingResource)jape.init());
pipeline.execute();
AnnotationSetImpl ann = (AnnotationSetImpl) doc.getAnnotations();
System.out.println(" ...Total annotation "+ann.getAllTypes());
This is another option if you want to update the ANNIE pipeline.
First get a list of the default/existing processing resources in your pipeline
Create an instance of your JAPE rule
Iterate over the list of existing processing resources adding each to a new collection. Add your own custom JAPE rule to this collection.
When you execute your ANNIE pipeline your JAPE rule will automatically be picked up so no need to specify document paths or execute individually.
Sample code:
File pluginsHome = Gate.getPluginsHome();
File anniePlugin = new File(pluginsHome, "ANNIE");
File annieGapp = new File(anniePlugin, "ANNIE_with_defaults.gapp");
annieController = (CorpusController) PersistenceManager.loadObjectFromFile(annieGapp);
LanguageAnalyser jape = (LanguageAnalyser)Factory.createResource(
"gate.creole.Transducer", gate.Utils.featureMap(
"grammarURL", new URL("file:///C://Program Files//gate-7.1//plugins//ANNIE//resources//NE//opensource.jape"),
"encoding", "UTF-8"));
Collection<ProcessingResource> newPRS = new ArrayList<ProcessingResource>();
Collection<ProcessingResource> prs = annieController.getPRs();
for(ProcessingResource resource: prs){
newPRS.add(resource);
}
newPRS.add((ProcessingResource)jape.init());
annieController.setPRs(newPRS);
Related
I'm using iText to create a PDF from a PDF template which is then emailed. The code is to be executed repeatedly. The created temporary file can't be deleted or overwritten. The error message is "The process cannot access the file 'Tmp.pdf' because it is being used by another process."
string path = Server.MapPath("files");
string tmp = path + #"\Tmp.pdf";
PdfDocument pdfDoc = new PdfDocument(new PdfReader(path + #"\Template.pdf"), new PdfWriter(tmp));
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
form.GetField("Content").SetValue(tmpItems.Text);
form.FlattenFields();
pdfDoc.Close();
// Email PDF
MailMessage mailMsg = new MailMessage();
Attachment data = new Attachment(tmp, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(tmp);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(tmp);
disposition.ReadDate = System.IO.File.GetLastAccessTime(tmp);
mailMsg.Attachments.Add(data);
File.Delete(tmp);
I assumed the file had been closed (pdfDoc.Close();) releasing the resource. The second time the code snippet is used (to create another version to be emailed) to overwrite the file, the error occurs at line 3. As a potential fix, I tried to delete the file but again the error occurs at the deletion point.
This is a very short snippet of code. What is the other process holding on to the file? What am I doing wrong?
I have an ASP.NET project that sends its logs to NLog.
However in this project, I have my own NLog logger and I would like to know how to route all the logs through it.
I guess I shouldn't add NLog as a logger, but I should find a way to register a method that will get called each time ASP tries to log anything.
How can this be accomplished?
This is the code that creates the logger:
// create the module name
var ProcessName = Process.GetCurrentProcess().ProcessName;
_ModuleName = ProcessName + " (\"" + Oracle.GuessMyName() + "\")";
// create the logger configuration
var Configuration = new LoggingConfiguration();
// create the file target
var FileTarget = new FileTarget ("file")
{
FileName = #"x:\Logs\${processname}.log",
ArchiveFileName = #"x:\Logs\${processname}.{#}.log",
Layout = #"${longdate}|${logger}|${level}|${message}${onexception:|Exception occurred:${exception:format=tostring}${newline}",
ArchiveEvery = FileArchivePeriod.Day,
ArchiveNumbering = ArchiveNumberingMode.Rolling,
MaxArchiveFiles = 7,
ConcurrentWrites = true
};
Configuration.AddTarget(FileTarget);
// create the viewer target
var ViewerTarget = new NLogViewerTarget ("viewer")
{
Layout = #"${message}${onexception:${newline} --> Exception occurred\:${exception:format=tostring}",
IncludeSourceInfo = true,
IncludeCallSite = true,
Address = #"udp://127.0.0.1:9999"
};
Configuration.AddTarget(ViewerTarget);
// set the rules
Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, FileTarget));
Configuration.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, ViewerTarget));
// set the configuration
LogManager.Configuration = Configuration;
// create a new logger
_Logger = LogManager.GetLogger(_ModuleName);
and this is also how ASP.net gets attached to nlog:
LoggerFactory.AddNLog();
Application.AddNLogWeb();
Now the current log layout looks like this for two process (the animal names are automatically changing every time the process is restarted)
so both process: shinobi and mouserun here have their own log output, but anything ASP related goes to ASP's nlog instance called Microsoft, regardless of the process.
the goal is to have the ASP output of shinobi to go in the shinobi logger and the mouserun ASP output to go in the mouserun logger.
Look at the code of NLog.Extensions.Logging, where it injects its own custom log-provider.
You can do the same and just wrap your global-logger object:
https://github.com/NLog/NLog.Extensions.Logging/blob/e48d6cc54d9abd70d976066265c7992117cbac5a/src/NLog.Extensions.Logging/NLogLoggerProvider.cs
https://github.com/NLog/NLog.Extensions.Logging/blob/1474ffe5b26d2ac95534ed01ef259133133bfb67/src/NLog.Extensions.Logging/NLogLoggerFactory.cs
https://github.com/NLog/NLog.Extensions.Logging/blob/2c05a4fbdda0fe026e60814d535e164e18786aef/src/NLog.Extensions.Logging/ConfigureExtensions.cs
public static ILoggerFactory AddNLog(this ILoggerFactory factory, NLogProviderOptions options)
{
ConfigureHiddenAssemblies();
using (var provider = new NLogLoggerProvider(options))
{
factory.AddProvider(provider);
}
return factory;
}
You could also create a custom-target, and redirect all non-global-logger messages to this target using NLog rules:
https://github.com/nlog/NLog/wiki/Configuration-file#rules
The custom target can then just forward the log-event to the global-logger:
https://github.com/NLog/NLog/wiki/How-to-write-a-custom-target
You should be careful with cyclic logging. Maybe have a filter in the custom-target to ignore messages from the global-logger.
But I think this is an ugly solution, and I fail to understand the restriction of only one logger-object. Especially when the reason is because it should be named after the application. Why not not a global variable for the name instead of abusing the logger-name?
Alternative you can create a custom target wrapper, that fixes the Logger on LogEventInfo's, so when forwarded to the wrapped target (UDP- / File-target), then it looks like they are all come from the same logger.
Similar to what this guy is trying to do:
https://github.com/NLog/NLog/issues/2352
Again really ugly solution, and should only be used when not able to figure out, how to avoid using the logger-name in the configuration of the wanted Nlog-targets (Ex. configure file-target-filename using something else).
I am attempting to create a DocuSign envelope from a template document using the CreateEnvelopeFromTemplates method, available within their v3 SOAP API web service. This is being instantiated from a asp.NET v4.0 web site.
Upon calling the method armed with the required parameter objects being passed in. I am recieving an exception from the web service, basically telling me that the Template ID is not a valid GUID.
669393: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Line 14889:
Line 14890: public DocuSignDSAPI.EnvelopeStatus CreateEnvelopeFromTemplates(DocuSignDSAPI.TemplateReference[] TemplateReferences, DocuSignDSAPI.Recipient[] Recipients, DocuSignDSAPI.EnvelopeInformation EnvelopeInformation, bool ActivateEnvelope) {
Line 14891: return base.Channel.CreateEnvelopeFromTemplates(TemplateReferences, Recipients, EnvelopeInformation, ActivateEnvelope);
Line 14892: }
Line 14893:
The template reference, a guid. Must be specified as the "Template" string property against TemplateReference object. This is then added to a dynamic array of TemplateReferences, which is one of the input parameters of the CreateEnvelopeFromTemplates method.
Actual template GUID: f37b4d64-54e3-4723-a6f1-a4120f0e9695
I am building up my template reference object using the following function that i wrote to try and make the functionality reusable:
Private Function GetTemplateReference(ByVal TemplateID As String) As TemplateReference
Dim templateReference As New TemplateReference
Dim guidTemplateID As Guid
With TemplateReference
.TemplateLocation = TemplateLocationCode.Server
If Guid.TryParse(TemplateID, guidTemplateID) Then
.Template = guidTemplateID.ToString
End If
End With
Return TemplateReference
End Function
The TemplateID is being passed in from a appSetting configuration value at the time of the TemplateReferences array instantiation like so...
templateReferences = New TemplateReference() {GetTemplateReference(ConfigurationManager.AppSettings("DocuSignTemplate_Reference"))}
recipients = New Recipient() {AddRecipient("myself#work.email", "My Name")}
envelopeInformation = CreateEnvelopeInformation()
envelopeStatus = client.CreateEnvelopeFromTemplates(templateReferences, recipients, envelopeInformation, True)
As you can see from my GetTemplateReference function I am also parsing the GUID before setting it back as a string so i know its valid. The template is managed and stored at the DocuSign end, hence specifying the document location.
I am referring to their own documentation:
CreateEnvelopeFromTemplates
Why oh why is the method not liking my Template ID? I can successfully use their REST API to call the same method, using their own code samples. Worst case I can make use of this but would rather interact with the web service as I would need to construct all the relevent requests in either XML or JSON.
I would really appreciate if someone could perhaps shed some light on this problem.
Thanks for taking the time to read my question!
Andrew might be spot on with the AccountId mention - are you setting the AccountId in the envelope information object? Also, have you seen the DocuSign SOAP SDK up on Github? That has 5 sample SOAP projects including one MS.NET project. The .NET project is in C# not Visual Basic, but still I think it will be helpful to you. Check out the SOAP SDK here:
https://github.com/docusign/DocuSign-eSignature-SDK
For instance, here is the test function for the CreateEnvelopeFromTemplates() function:
public void CreateEnvelopeFromTemplatesTest()
{
// Construct all the recipient information
DocuSignWeb.Recipient[] recipients = HeartbeatTests.CreateOneSigner();
DocuSignWeb.TemplateReferenceRoleAssignment[] finalRoleAssignments = new DocuSignWeb.TemplateReferenceRoleAssignment[1];
finalRoleAssignments[0] = new DocuSignWeb.TemplateReferenceRoleAssignment();
finalRoleAssignments[0].RoleName = recipients[0].RoleName;
finalRoleAssignments[0].RecipientID = recipients[0].ID;
// Use a server-side template -- you could make more than one of these
DocuSignWeb.TemplateReference templateReference = new DocuSignWeb.TemplateReference();
templateReference.TemplateLocation = DocuSignWeb.TemplateLocationCode.Server;
// TODO: replace with template ID from your account
templateReference.Template = "server template ID";
templateReference.RoleAssignments = finalRoleAssignments;
// Construct the envelope information
DocuSignWeb.EnvelopeInformation envelopeInfo = new DocuSignWeb.EnvelopeInformation();
envelopeInfo.AccountId = _accountId;
envelopeInfo.Subject = "create envelope from templates test";
envelopeInfo.EmailBlurb = "testing docusign creation services";
// Create draft with all the template information
DocuSignWeb.EnvelopeStatus status = _apiClient.CreateEnvelopeFromTemplates(new DocuSignWeb.TemplateReference[] { templateReference },
recipients, envelopeInfo, false);
// Confirm that the envelope has been assigned an ID
Assert.IsNotNullOrEmpty(status.EnvelopeID);
Console.WriteLine("Status for envelope {0} is {1}", status.EnvelopeID, status.Status);
}
This code calls other sample functions in the SDK which I have not included, but hopefully this helps shed some light on what you're doing wrong...
This problem arises when you don't set up the field AccountId. This field can be retrieved from your account. In Docusign's console go to Preferences / API and look here
Where to find AccountID Guid in Docusign's Console
Use API Account ID (which is in GUID format) and you should be OK.
I am invoking the Tridion 2011 SP1 core service via the shipped client assembly. When I attempt to list the contents of a publication, I get an exception.
The code (simplified) looks like this:
ItemsFilterData filter = new Tridion.ContentManager.CoreService
.Client.RepositoryItemsFilterData.RepositoryItemsFilterData();
filter.ItemTypes = new ItemType[] {
ItemType.Folder,
ItemType.StructureGroup
};
filter.Recursive = false;
IEnumerable<IdentifiableObjectData> childItems = core.GetList("tcm:0-15-1", filter);
Note: the variable "core" refers to an ISessionAwareCoreService which I can successfully use to call, for example core.GetSystemWideList()
When .GetList is invoked, I get the following exception:
System.ServiceModel.FaultException`1 was unhandled
Message=Unexpected list type:
Tridion.ContentManager.Data.ContentManagement.RepositoryItemsFilterData.
What are the possible causes of this problem? Can you suggest a good general approach for interpreting this kind of message?
You can't get the direct children of a Publication using GetList. Instead you should just load the PublicationData with a client.Read and then access the RootFolder and RootStructureGroup on that.
PublicationData pub = (PublicationData)core.Read("tcm:0-1-1", new ReadOptions());
string rootFolder = pub.RootFolder.IdRef;
string rootSG = pub.RootStructureGroup.IdRef;
Alternatively you can call GetListXml with your RepositoryItemsFilterData and extract the items from the XML yourself.
XElement listResult = core.GetListXml(parent.ID, filter);
I am trying to upload a file with the FileUpload control. When file is uploaded, I extract information from it and then i want to delete it.
I manage to upload it, save it and get the info from it, but when i try to delete it i get the follwing exception
"The process cannot access the file 'D:\IIS**OMITTED***\V75 personal ny.csv' because it is being used by another process.
string fn = Path.GetFileName(fu.PostedFile.FileName);
string SaveLocation = Server.MapPath("UploadedCSVFiles") + "\\" + fn;
FileInfo fi = new FileInfo(SaveLocation);
fu.PostedFile.SaveAs(SaveLocation);
fu.PostedFile.InputStream.Dispose();
DataTable dt = AMethodThatUsesFile(SaveLocation);
fi.Delete();
Try this code to delete file.
System.IO.File.Delete(SaveLocation );
You specified a method AMethodThatUsesFile(SaveLocation);. If it uses any classes like StreamReader to read file, please close the reader using StreamReader.Close(); method before trying to delete
dispose the fi before deleting. and then us File.Delete(). remember to use using statements when use disposable objects, or dispose it after use.
using System.io
File.Delete(Server.MapPath("../Nurturing/" + fnevents));
FileInfo fInfoEvent;
fInfoEvent = new FileInfo(fnevents);
fInfoEvent.Delete();
here fnevents is the name of the file that u are deleting. Nurturing is the name of the folder.