diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index 3a621b0d..0a5cba9b 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -45,6 +45,7 @@ grails.project.dependency.resolution = { compile('lib:itextpdf:5.4.0') compile('lib:itext-pdfa:5.4.0') compile('lib:itext-xtra:5.4.0') + compile('lib:jbibtex:1.0.3') // runtime 'mysql:mysql-connector-java:5.1.16' } diff --git a/grails-app/conf/UrlMappings.groovy b/grails-app/conf/UrlMappings.groovy index 16428130..f4a209e1 100644 --- a/grails-app/conf/UrlMappings.groovy +++ b/grails-app/conf/UrlMappings.groovy @@ -7,6 +7,11 @@ class UrlMappings { } } + "/bibtexFileController/upload" { + controller = "bibtexFile" + action = "upload" + } + "/"(controller: "Auth", action: "index") "500"(view:'/error') } diff --git a/grails-app/controllers/rgms/publication/BibtexFileController.groovy b/grails-app/controllers/rgms/publication/BibtexFileController.groovy new file mode 100644 index 00000000..436cc282 --- /dev/null +++ b/grails-app/controllers/rgms/publication/BibtexFileController.groovy @@ -0,0 +1,51 @@ +package rgms.publication + +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +/** + * + * @author Diogo Vinícius + * + */ +class BibtexFileController { + + def index() {} + + def upload () { + MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest )request + CommonsMultipartFile cmf = (CommonsMultipartFile)multiRequest.getFile("file") + byte[] bytes = cmf.bytes + File file = new File("web-app//uploads//temp.bibtex") + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)) + bos.write(bytes) + bos.close() + + System.out.println("********** " + file.getBytes().size()); + + BibtexFile bibtexFile = transform(file) + + System.out.println("********** " + bibtexFile.getPublications().size()) + for (Publication publication : bibtexFile.getPublications()) { + System.out.println("************* " + publication); + System.out.println("************************** School : " + publication.getSchool()); + System.out.println("************************** Address: " + publication.getAddress()); + System.out.println("************************** Title : " + publication.getTitle()); + System.out.println("************************** Date : " + publication.getPublicationDate()); + if (publication.save(failOnError: true)) { + System.out.println("salvando o objeto"); + } + } + redirect(action: "home") + + } + + def home () { + + } + + def BibtexFile transform(file) { + return new BibtexFile(file) + } + +} diff --git a/grails-app/domain/rgms/publication/BibtexFile.groovy b/grails-app/domain/rgms/publication/BibtexFile.groovy new file mode 100644 index 00000000..b27c7680 --- /dev/null +++ b/grails-app/domain/rgms/publication/BibtexFile.groovy @@ -0,0 +1,54 @@ +package rgms.publication + +import java.util.Collection; + +import java.io.BufferedReader +import java.io.File; +import java.io.FileInputStream +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader +import java.io.Reader; +import java.util.ArrayList +import java.util.List + +import org.jbibtex.BibTeXEntry; +import org.jbibtex.Value; +import org.jbibtex.BibTeXDatabase; +import org.jbibtex.BibTeXEntry; +import org.jbibtex.BibTeXParser; +import org.jbibtex.BibTeXString; +import org.jbibtex.Key; +import org.jbibtex.ParseException; + +import rgms.member.Member + +/** + * + * @author Diogo Vinícius + * + */ +class BibtexFile { + + List publications = new ArrayList() + Member member + + public BibtexFile(file) { + publications = BibtexParse.generatePublications(file) + } + + public List getPublications() { + return this.publications + } + + public List getPublications(Class clazz) { + List publicationsFiltered = new ArrayList() + for (Publication publication : this.getPublications()) { + if (publication.getClass().getName().equals(clazz.getName())) { + publicationsFiltered.add(publication) + } + } + return publicationsFiltered + } + +} diff --git a/grails-app/domain/rgms/publication/BibtexParse.groovy b/grails-app/domain/rgms/publication/BibtexParse.groovy new file mode 100644 index 00000000..59e61fc7 --- /dev/null +++ b/grails-app/domain/rgms/publication/BibtexParse.groovy @@ -0,0 +1,116 @@ +package rgms.publication + +import org.jbibtex.BibTeXDatabase +import org.jbibtex.BibTeXEntry; +import org.jbibtex.BibTeXParser +import org.jbibtex.BibTeXString +import org.jbibtex.Key +import org.jbibtex.ParseException +import org.jbibtex.Value + +/** + * + * @author Diogo Vinícius + * + */ +class BibtexParse { + + public static List generatePublications(File file) { + List publications = new ArrayList() + BibTeXDatabase bibtexDatabase = parseBibTeX(file) + Collection entries = bibtexDatabase.getEntries().values(); + + for(BibTeXEntry entry : entries){ + //TODO settar todos os atributos de acordo com a classe a ser instanciada + //Para pegar os valores do objeto 'entry' basta seguir o modelo da linha abaixo + //String value = entry.getField(BibTeXEntry.KEY_TITLE).toUserString(); + if (entry.getType().equals(BibTeXEntry.TYPE_ARTICLE)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_BOOK)) { + publications.add(new BookChapter()) + } + else if (entry.getType().equals(BibTeXEntry.TYPE_BOOKLET)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_CONFERENCE)) { + publications.add(new Conferencia()) + } + else if (entry.getType().equals(BibTeXEntry.TYPE_INBOOK)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_INCOLLECTION)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_INPROCEEDINGS)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_MANUAL)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_MASTERSTHESIS)) { + Dissertacao dissertacao = new Dissertacao() + dissertacao.setTitle(entry.getField(BibTeXEntry.KEY_TITLE).toUserString()) + dissertacao.setSchool(entry.getField(BibTeXEntry.KEY_SCHOOL).toUserString()) + dissertacao.setAddress(entry.getField(BibTeXEntry.KEY_ADDRESS).toUserString()) + dissertacao.setPublicationDate(new Date())//TODO transformar o date para setar no objeto + dissertacao.setFile("file")//TODO tirar a obrigatoriedade. futuramente processar a url para importar + publications.add(dissertacao) + } + else if (entry.getType().equals(BibTeXEntry.TYPE_MISC)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_PHDTHESIS)) { + Tese tese = new Tese() + tese.setTitle(entry.getField(BibTeXEntry.KEY_TITLE).toUserString()) + tese.setSchool(entry.getField(BibTeXEntry.KEY_SCHOOL).toUserString()) + tese.setAddress(entry.getField(BibTeXEntry.KEY_ADDRESS).toUserString()) + tese.setPublicationDate(new Date())//TODO transformar o date para setar no objeto + tese.setFile("file")//TODO settar corretamente este atributo + publications.add(tese) + } + else if (entry.getType().equals(BibTeXEntry.TYPE_PROCEEDINGS)) { + + } + else if (entry.getType().equals(BibTeXEntry.TYPE_TECHREPORT)) { + publications.add(new TechnicalReport()) + } + else if (entry.getType().equals(BibTeXEntry.TYPE_UNPUBLISHED)) { + + } + + } + + return publications + + } + + private static BibTeXDatabase parseBibTeX(File file) throws IOException, ParseException { + Reader reader = new FileReader(file); + + try { + BibTeXParser parser = new BibTeXParser(){ + + @Override + public void checkStringResolution(Key key, BibTeXString string){ + + if(string == null){ + System.err.println("Unresolved string: \"" + key.getValue() + "\""); + } + } + + @Override + public void checkCrossReferenceResolution(Key key, BibTeXEntry entry){ + + if(entry == null){ + System.err.println("Unresolved cross-reference: \"" + key.getValue() + "\""); + } + } + }; + + return parser.parse(reader); + } finally { + reader.close(); + } +} +} diff --git a/grails-app/views/bibtexFile/home.gsp b/grails-app/views/bibtexFile/home.gsp new file mode 100644 index 00000000..0e768874 --- /dev/null +++ b/grails-app/views/bibtexFile/home.gsp @@ -0,0 +1,17 @@ +<%@ page contentType="text/html;charset=UTF-8" %> + + + + +Insert title here + + +
+
+ + + + +
+ + \ No newline at end of file diff --git a/grails-app/views/initial.gsp b/grails-app/views/initial.gsp index 88654470..44c2eda6 100644 --- a/grails-app/views/initial.gsp +++ b/grails-app/views/initial.gsp @@ -145,6 +145,7 @@
  • Technical Report
  • Tese
  • Orientation
  • +
  • Import Bibtex File
  • diff --git a/grails-app/views/tese/list.gsp b/grails-app/views/tese/list.gsp index 59c4ec5d..cc621df6 100644 --- a/grails-app/views/tese/list.gsp +++ b/grails-app/views/tese/list.gsp @@ -32,7 +32,7 @@ - + <%-- g:sortableColumn property="bibTex" title="${message(code: 'tese.bibTex.label', default: 'Bib Tex')}" / --%> @@ -50,7 +50,7 @@ ${fieldValue(bean: teseInstance, field: "researchLine")} - ${fieldValue(bean: teseInstance, field: "bibTex")} + <%-- td>${fieldValue(bean: teseInstance, field: "bibTex")} ${fieldValue(bean: teseInstance, field: "school")} diff --git a/lib/jbibtex-1.0.3.jar b/lib/jbibtex-1.0.3.jar new file mode 100644 index 00000000..6b47eeac Binary files /dev/null and b/lib/jbibtex-1.0.3.jar differ diff --git a/test/cucumber/BibtexImport.feature b/test/cucumber/BibtexImport.feature index d9cfe7e1..ca9a8498 100644 --- a/test/cucumber/BibtexImport.feature +++ b/test/cucumber/BibtexImport.feature @@ -21,7 +21,7 @@ Feature: BibtexImport Scenario: bibtex file with several publication types Given I am on Import Bibtex File Menu When I click "Choose file" - And selected a bibtex file with one Book Chapter and two Technical Report and I click "Import" - Then is created one Book Chapter publication - And is created two Technical Report publications - And one Book Chapter is stored and two Technical Report is stored \ No newline at end of file + And selected a bibtex file with one Dissertacao and two Tese and I click "Import" + Then is created one Dissertacao publication + And is created two Tese publications + And one Dissertacao is stored and two Tese is stored \ No newline at end of file diff --git a/test/cucumber/steps/BibtexImportSteps.groovy b/test/cucumber/steps/BibtexImportSteps.groovy index 68155516..1b3fe916 100644 --- a/test/cucumber/steps/BibtexImportSteps.groovy +++ b/test/cucumber/steps/BibtexImportSteps.groovy @@ -1,68 +1,59 @@ +import junit.framework.Test; +import rgms.publication.*; import cucumber.runtime.PendingException; +import rgms.publication.BibtexFile; import static cucumber.api.groovy.EN.* //You can implement missing steps with the snippets below: Given(~'^I am on Import Bibtex File Menu$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } When(~'^I click "([^"]*)"$') { String arg1 -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } When(~'^selected a bibtex file and I click "([^"]*)"$') { String arg1 -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } Then(~'^is created all corresponding publications$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() + BibtexFileController bibtexFileController = new BibtexFileController() + BibtexFile bibtexFile = bibtexFileController.transform(new File("test//cucumber//steps//sample.bibtex")) + assert bibtexFile.getPublications().size() == 3 } Then(~'^all of then are stored$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } When(~'^selected a bibtex file unformatted and I click "([^"]*)"$') { String arg1 -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } +//@Test(expected=RuntimeException.class) Then(~'^the system output the message error "([^"]*)"$') { String arg1 -> - // Express the Regexp above with the code you wish you had - throw new PendingException() + BibtexFileController bibtexFileController = new BibtexFileController() + BibtexFile bibtexFile = bibtexFileController.transform(new File("test//cucumber//steps//sample.bibtex")) } Then(~'^none publication is stored$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } -When(~'^selected a bibtex file with one Book Chapter and two Technical Report and I click "([^"]*)"$') { String arg1 -> - // Express the Regexp above with the code you wish you had - throw new PendingException() +When(~'^selected a bibtex file with one Dissertacao and two Tese and I click "([^"]*)"$') { String arg1 -> } -Then(~'^is created one Book Chapter publication$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() +Then(~'^is created one Dissertacao publication$') { -> + BibtexFileController bibtexFileController = new BibtexFileController() + BibtexFile bibtexFile = bibtexFileController.transform(new File("test//cucumber//steps//sample.bibtex")) + assert bibtexFile.getPublications(Conferencia.class).isEmpty() + assert bibtexFile.getPublications(Dissertacao.class).size() == 1 } -Then(~'^is created two Technical Report publications$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() +Then(~'^is created two Tese publications$') { -> + BibtexFileController bibtexFileController = new BibtexFileController() + BibtexFile bibtexFile = bibtexFileController.transform(new File("test//cucumber//steps//sample.bibtex")) + assert bibtexFile.getPublications(TechnicalReport.class).isEmpty() + assert bibtexFile.getPublications(Tese.class).size() == 2 } -Then(~'^one Book Chapter is stored and two Technical Report is stored$') { -> - // Express the Regexp above with the code you wish you had - throw new PendingException() +Then(~'^one Dissertacao is stored and two Tese is stored$') { -> } When(~'^I click on "([^"]*)" option at Technical Report list$') { String arg1 -> - // Express the Regexp above with the code you wish you had - throw new PendingException() } \ No newline at end of file diff --git a/test/cucumber/steps/sample.bibtex b/test/cucumber/steps/sample.bibtex new file mode 100644 index 00000000..14302fb7 --- /dev/null +++ b/test/cucumber/steps/sample.bibtex @@ -0,0 +1,26 @@ +@MASTERSTHESIS{Gor:2008, + author = {Samir Gorsky}, + title = {A semântica algébrica para as lógicas modais e seu interesse filosófico}, + school = {IFCH-UNICAMP}, + year = {2008}, + address = {Campinas, Brazil}, + note = {\\ URL = http://samirgorsky.vilabol.uol.com.br/logicamodal.pdf}, +} + +@PHDTHESIS{dCosta_1963_Inconsistent_Formal_Systems, + author = {N. C. A. da Costa}, + title = "Inconsistent Formal Systems \emph{(in Portuguese)}", + school = {Federal University of Parana}, + year = {1963}, + address = "Curitiba, Brazil", + note = {Edited by Editora UFPR, Curitiba, 1993}, +} + +@PHDTHESIS{diogo_doctor, + author = {D. V. de S. Silva}, + title = "Doctor Thesis", + school = {Federal University of Pernambuco}, + year = {2013}, + address = "Recife, Brazil", + note = {Edited by Editora UFPE, Recife, 2013}, +} \ No newline at end of file