/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.javaparser;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openflexo.foundation.dm.DMMethod;
import org.openflexo.foundation.dm.DMModel;
import org.openflexo.foundation.dm.DMProperty;
import org.openflexo.foundation.dm.DuplicateMethodSignatureException;
import org.openflexo.foundation.dm.javaparser.JavaClassParser;
import org.openflexo.foundation.dm.javaparser.JavaFieldParser;
import org.openflexo.foundation.dm.javaparser.JavaMethodParser;
import org.openflexo.foundation.dm.javaparser.JavaParseException;
import org.openflexo.foundation.dm.javaparser.ParsedJavaClass;
import org.openflexo.foundation.dm.javaparser.ParsedJavaField;
import org.openflexo.foundation.dm.javaparser.ParsedJavaMethod;
import org.openflexo.foundation.dm.javaparser.ParsedJavaMethod.ParsedJavaMethodParameter;
import org.openflexo.foundation.dm.javaparser.ParsedJavadoc;
import org.openflexo.foundation.dm.javaparser.ParsedJavadocItem;
import org.openflexo.javaparser.FJPTypeResolver.CrossReferencedEntitiesException;
import org.openflexo.toolbox.StringUtils;
import com.thoughtworks.qdox.parser.ParseException;
public class DefaultJavaParser implements JavaClassParser, JavaMethodParser, JavaFieldParser {
private static final Logger logger = Logger.getLogger(DefaultJavaParser.class.getPackage().getName());
@Override
public ParsedJavadoc parseJavadocForClass(String classCode, DMModel dataModel) throws JavaParseException {
try {
String sourceName = "TemporaryClass";
FJPJavaSource source = new FJPJavaSource(sourceName, classCode, dataModel.getClassLibrary());
FJPJavaClass parsedClass = source.getRootClass();
return parsedClass.getJavadoc();
}
catch (ParseException e) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Parse error");
}
throw new JavaParseException();
}
}
@Override
public ParsedJavaClass parseClass(String classCode, DMModel dataModel) throws JavaParseException {
try {
String sourceName = "TemporaryClass";
FJPJavaSource source = new FJPJavaSource(sourceName, classCode, dataModel.getClassLibrary());
FJPJavaClass parsedClass = source.getRootClass();
return parsedClass;
}
catch (ParseException e) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Parse error");
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("Code: " + classCode);
}
throw new JavaParseException();
}
}
@Override
public FJPJavaMethod parseMethod(String methodCode, DMModel dataModel) throws JavaParseException {
try {
String parsedString = "public class TemporaryClass {" + StringUtils.LINE_SEPARATOR + methodCode + StringUtils.LINE_SEPARATOR
+ "}" + StringUtils.LINE_SEPARATOR;
if (logger.isLoggable(Level.FINE)) {
logger.fine("Parsing " + parsedString);
}
String sourceName = "TemporaryClass";
FJPJavaSource source = new FJPJavaSource(sourceName, parsedString, dataModel.getClassLibrary());
FJPJavaClass parsedClass = source.getRootClass();
if (parsedClass.getMethods().length == 0) {
return null;
}
FJPJavaMethod parsedMethod = parsedClass.getMethods()[0];
return parsedMethod;
}
catch (ParseException e) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Parse error: " + methodCode);
}
throw new JavaParseException();
}
}
@Override
public ParsedJavaField parseField(String fieldCode, DMModel dataModel) throws JavaParseException {
String parsedString = null;
try {
parsedString = "public class TemporaryClass {" + StringUtils.LINE_SEPARATOR + fieldCode + StringUtils.LINE_SEPARATOR + "}"
+ StringUtils.LINE_SEPARATOR;
if (logger.isLoggable(Level.FINE)) {
logger.fine("Parsing " + parsedString);
}
String sourceName = "TemporaryClass";
FJPJavaSource source = new FJPJavaSource(sourceName, parsedString, dataModel.getClassLibrary());
FJPJavaClass parsedClass = source.getRootClass();
if (parsedClass.getFields().length == 0) {
return null;
}
FJPJavaField parsedField = parsedClass.getFields()[0];
return parsedField;
}
catch (ParseException e) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Parse error: " + fieldCode);
}
throw new JavaParseException();
}
}
@Override
public ParsedJavadoc parseJavadocForMethod(String methodCode, DMModel dataModel) throws JavaParseException {
try {
String parsedString = "public class TemporaryClass {" + StringUtils.LINE_SEPARATOR + methodCode + StringUtils.LINE_SEPARATOR
+ "}" + StringUtils.LINE_SEPARATOR;
if (logger.isLoggable(Level.FINE)) {
logger.fine("Parsing " + parsedString);
}
String sourceName = "TemporaryClass";
FJPJavaSource source = new FJPJavaSource(sourceName, parsedString, dataModel.getClassLibrary());
FJPJavaClass parsedClass = source.getRootClass();
if (parsedClass.getMethods().length == 0) {
return null;
}
FJPJavaMethod parsedMethod = parsedClass.getMethods()[0];
return parsedMethod.getJavadoc();
}
catch (ParseException e) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Parse error");
}
throw new JavaParseException();
}
}
@Override
public ParsedJavadoc parseJavadocForField(String fieldCode, DMModel dataModel) throws JavaParseException {
try {
String parsedString = "public class TemporaryClass {" + StringUtils.LINE_SEPARATOR + fieldCode + StringUtils.LINE_SEPARATOR
+ "}" + StringUtils.LINE_SEPARATOR;
if (logger.isLoggable(Level.FINE)) {
logger.fine("Parsing " + parsedString);
}
String sourceName = "TemporaryClass";
FJPJavaSource source = new FJPJavaSource(sourceName, parsedString, dataModel.getClassLibrary());
FJPJavaClass parsedClass = source.getRootClass();
if (parsedClass.getFields().length == 0) {
return null;
}
FJPJavaField parsedField = parsedClass.getFields()[0];
return parsedField.getJavadoc();
}
catch (ParseException e) {
if (logger.isLoggable(Level.INFO)) {
logger.info("Parse error");
}
throw new JavaParseException();
}
}
public static void main(String[] args) {
DefaultJavaParser parser = new DefaultJavaParser();
String codeToParse = "/**" + StringUtils.LINE_SEPARATOR + " * description first line" + StringUtils.LINE_SEPARATOR
+ " * description second line" + StringUtils.LINE_SEPARATOR + " * description third line" + StringUtils.LINE_SEPARATOR
+ " * " + StringUtils.LINE_SEPARATOR + " * @doc UserManual a description for user manual" + StringUtils.LINE_SEPARATOR
+ " * @doc Technical a technical description" + StringUtils.LINE_SEPARATOR + " * @param param1 param1 description"
+ StringUtils.LINE_SEPARATOR + " * @param param2 param2 description" + StringUtils.LINE_SEPARATOR
+ " * @param param3 param3 description" + StringUtils.LINE_SEPARATOR + " * @return foo" + StringUtils.LINE_SEPARATOR
+ " */" + StringUtils.LINE_SEPARATOR + "public a() {}";
try {
ParsedJavadoc jd = parser.parseJavadocForMethod(codeToParse, null);
if (logger.isLoggable(Level.INFO)) {
for (ParsedJavadocItem d : jd.getDocletTags()) {
logger.info("tag " + d.getTag() + " name=[" + d.getParameterName() + "] value=(" + d.getParameterValue() + ")");
}
logger.info("jd comment=" + jd.getComment());
}
} catch (JavaParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void updateWith(DMMethod method, ParsedJavaMethod javaMethod) throws DuplicateMethodSignatureException {
FJPJavaMethod parsedMethod = (FJPJavaMethod) javaMethod;
FJPJavaClass parsedClass = parsedMethod.getParentClass();
FJPJavaSource source = parsedMethod.getJavaSource();
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update method " + method + " from parsed method");
}
try {
DMMethod updatedMethod = FJPDMMapper.makeMethod(parsedClass, parsedMethod.getCallSignature(), method.getDMModel(), null,
source, false);
if (updatedMethod == null) {
logger.warning("Could not lookup method " + updatedMethod);
return;
} else {
method.update(updatedMethod, true);
}
} catch (CrossReferencedEntitiesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update method " + method + " from parsed method: DONE ");
}
}
@Override
public void updateGetterWith(DMProperty property, ParsedJavaMethod javaMethod) throws DuplicateMethodSignatureException {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update property " + property + " from parsed getter method");
}
if (javaMethod.getJavadoc() != null) {
property.setDescription(javaMethod.getJavadoc().getComment());
}
// TODO: we can handle type reinjection here
// TODO: handle 'static' here
}
@Override
public void updateSetterWith(DMProperty property, ParsedJavaMethod javaMethod) throws DuplicateMethodSignatureException {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update property " + property + " from parsed setter method");
}
if (javaMethod.getMethodParameters().size() == 1) {
ParsedJavaMethodParameter setterParam = javaMethod.getMethodParameters().firstElement();
property.setSetterParamName(setterParam.getName());
}
// TODO: we can handle type reinjection here
// TODO: handle 'static' here
}
@Override
public void updateAdditionAccessorWith(DMProperty property, ParsedJavaMethod javaMethod) throws DuplicateMethodSignatureException {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update property " + property + " from parsed addition method");
}
if (javaMethod.getMethodParameters().size() == 1) {
ParsedJavaMethodParameter additionMethodParam = javaMethod.getMethodParameters().firstElement();
property.setAdditionAccessorParamName(additionMethodParam.getName());
}
// TODO: we can handle type reinjection here
// TODO: we can also handle key type reinjection here
// TODO: handle 'static' here
}
@Override
public void updateRemovalAccessorWith(DMProperty property, ParsedJavaMethod javaMethod) throws DuplicateMethodSignatureException {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update property " + property + " from parsed removal method");
}
if (javaMethod.getMethodParameters().size() == 1) {
ParsedJavaMethodParameter removalMethodParam = javaMethod.getMethodParameters().firstElement();
property.setRemovalAccessorParamName(removalMethodParam.getName());
}
// TODO: we can handle key type reinjection here
// TODO: handle 'static' here
}
@Override
public void updatePropertyFromJavaField(DMProperty property, ParsedJavaField javaField) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Try to update property " + property + " from parsed field");
// TODO implement this
// TODO: handle 'static' here
}
}
}