Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d57f629

Browse files
committed
Java Generics, Java Fields as Association, Java Method's Throw clauses
1 parent 8f1bdf8 commit d57f629

File tree

6 files changed

+379
-229
lines changed

6 files changed

+379
-229
lines changed

JavaReverseEngineer.js

Lines changed: 137 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ define(function (require, exports, module) {
4040

4141
require("grammar/java7");
4242

43-
4443
var javaPrimitiveTypes = [
4544
"void",
4645
"byte",
@@ -122,9 +121,14 @@ define(function (require, exports, module) {
122121
this._implementPendings = [];
123122

124123
/**
125-
* @member {{classifier:type.UMLClassifier, node: Object}}
124+
* @member {{classifier:type.UMLClassifier, association: type.UMLAssociation, node: Object}}
125+
*/
126+
this._associationPendings = [];
127+
128+
/**
129+
* @member {{operation:type.UMLOperation, node: Object}}
126130
*/
127-
this._fieldPendings = [];
131+
this._throwPendings = [];
128132

129133
/**
130134
* @member {{namespace:type.UMLModelElement, feature:type.UMLStructuralFeature, node: Object}}
@@ -187,7 +191,7 @@ define(function (require, exports, module) {
187191
* - Resolve Type References
188192
*/
189193
JavaAnalyzer.prototype.perform2ndPhase = function (options) {
190-
var i, len, _typeName, _type, _pathName;
194+
var i, len, j, len2, _typeName, _type, _pathName;
191195

192196
// Create Generalizations
193197
// if super type not found, create a Class correspond to the super type.
@@ -197,12 +201,13 @@ define(function (require, exports, module) {
197201
_type = this._findType(_extend.classifier, _typeName);
198202
if (!_type) {
199203
_pathName = this._toPathName(_typeName);
200-
if (_extend.node.kind === "class") {
201-
_type = this._ensureClass(this._root, _pathName);
202-
} else if (_extend.node.kind === "interface") {
204+
if (_extend.kind === "interface") {
203205
_type = this._ensureInterface(this._root, _pathName);
206+
} else {
207+
_type = this._ensureClass(this._root, _pathName);
204208
}
205209
}
210+
206211
var generalization = new type.UMLGeneralization();
207212
generalization._parent = _extend.classifier;
208213
generalization.source = _extend.classifier;
@@ -228,6 +233,53 @@ define(function (require, exports, module) {
228233
_implement.classifier.ownedElements.push(realization);
229234
}
230235

236+
// Create Associations
237+
for (i = 0, len = this._associationPendings.length; i < len; i++) {
238+
var _asso = this._associationPendings[i];
239+
_typeName = _asso.node.type.qualifiedName.name;
240+
_type = this._findType(_asso.classifier, _typeName);
241+
// if type found, add as Association
242+
if (_type) {
243+
for (j = 0, len2 = _asso.node.variables.length; j < len2; j++) {
244+
var variableNode = _asso.node.variables[j];
245+
// Create Association
246+
var association = new type.UMLAssociation();
247+
association._parent = _asso.classifier;
248+
_asso.classifier.ownedElements.push(association);
249+
// Set End1
250+
association.end1.reference = _asso.classifier;
251+
association.end1.name = "";
252+
association.end1.visibility = UML.VK_PACKAGE;
253+
association.end1.navigable = false;
254+
// TODO: Multiplicity
255+
// TODO: Aggregation?
256+
// Set End2
257+
association.end2.reference = _type;
258+
association.end2.name = variableNode.name;
259+
association.end2.visibility = this._getVisibility(_asso.node.modifiers);
260+
association.end2.navigable = true;
261+
}
262+
// if type not found, add as Attribute
263+
} else {
264+
this.translateFieldAsAttribute(options, _asso.classifier, _asso.node);
265+
}
266+
}
267+
268+
// Assign Throws to Operations
269+
for (i = 0, len = this._throwPendings.length; i < len; i++) {
270+
var _throw = this._throwPendings[i];
271+
_typeName = _throw.node.name;
272+
_type = this._findType(_throw.operation, _typeName);
273+
if (!_type) {
274+
_pathName = this._toPathName(_typeName);
275+
_type = this._ensureClass(this._root, _pathName);
276+
}
277+
278+
console.log(_type);
279+
280+
_throw.operation.raisedExceptions.push(_type);
281+
}
282+
231283
// Resolve Type References
232284
for (i = 0, len = this._typedFeaturePendings.length; i < len; i++) {
233285
var _typedFeature = this._typedFeaturePendings[i];
@@ -246,14 +298,14 @@ define(function (require, exports, module) {
246298
// otherwise
247299
} else {
248300
_pathName = this._toPathName(_typeName);
249-
var _newClass = this._ensureClass(this._builder.getBaseModel(), _pathName);
301+
var _newClass = this._ensureClass(this._root, _pathName);
250302
_typedFeature.feature.type = _newClass;
251303
}
252304
}
253305

254306
// Translate type's arrayDimension to multiplicity
255307
if (_typedFeature.node.arrayDimension && _typedFeature.node.arrayDimension.length > 0) {
256-
var j, len2, _dim = [];
308+
var _dim = [];
257309
for (j = 0, len2 = _typedFeature.node.arrayDimension.length; j < len2; j++) {
258310
_dim.push("*");
259311
}
@@ -514,7 +566,14 @@ define(function (require, exports, module) {
514566
var memberNode = memberNodeArray[i];
515567
switch (memberNode.node) {
516568
case "Field":
517-
this.translateField(options, namespace, memberNode);
569+
if (options.association) {
570+
this.translateFieldAsAssociation(options, namespace, memberNode);
571+
} else {
572+
this.translateFieldAsAttribute(options, namespace, memberNode);
573+
}
574+
break;
575+
case "Constructor":
576+
this.translateMethod(options, namespace, memberNode);
518577
break;
519578
case "Method":
520579
this.translateMethod(options, namespace, memberNode);
@@ -527,6 +586,31 @@ define(function (require, exports, module) {
527586
}
528587
};
529588

589+
590+
/**
591+
* Translate Java Type Parameter Nodes.
592+
* @param {Element} namespace
593+
* @param {Object} typeParameterNodeArray
594+
*/
595+
JavaAnalyzer.prototype.translateTypeParameters = function (options, namespace, typeParameterNodeArray) {
596+
if (typeParameterNodeArray) {
597+
var i, len, _typeParam;
598+
for (i = 0, len = typeParameterNodeArray.length; i < len; i++) {
599+
_typeParam = typeParameterNodeArray[i];
600+
if (_typeParam.node === "TypeParameter") {
601+
var _templateParameter = new type.UMLTemplateParameter();
602+
_templateParameter._parent = namespace;
603+
_templateParameter.name = _typeParam.name;
604+
if (_typeParam.type) {
605+
_templateParameter.parameterType = _typeParam.type;
606+
}
607+
namespace.templateParameters.push(_templateParameter);
608+
}
609+
}
610+
}
611+
};
612+
613+
530614
/**
531615
* Translate Java Class Node.
532616
* @param {Element} namespace
@@ -565,7 +649,8 @@ define(function (require, exports, module) {
565649
});
566650
}
567651
}
568-
652+
// Translate Type Parameters
653+
this.translateTypeParameters(options, _class, classNode.typeParameters);
569654
// Translate Types
570655
this.translateTypes(options, _class, classNode.body);
571656
// Translate Members
@@ -599,6 +684,8 @@ define(function (require, exports, module) {
599684
}
600685
}
601686

687+
// Translate Type Parameters
688+
this.translateTypeParameters(options, _interface, interfaceNode.typeParameters);
602689
// Translate Types
603690
this.translateTypes(options, _interface, interfaceNode.body);
604691
// Translate Members
@@ -620,6 +707,8 @@ define(function (require, exports, module) {
620707
_enum.visibility = this._getVisibility(enumNode.modifiers);
621708
namespace.ownedElements.push(_enum);
622709

710+
// Translate Type Parameters
711+
this.translateTypeParameters(options, _enum, enumNode.typeParameters);
623712
// Translate Types
624713
this.translateTypes(options, _enum, enumNode.body);
625714
// Translate Members
@@ -642,29 +731,48 @@ define(function (require, exports, module) {
642731
_annotationType.visibility = this._getVisibility(annotationTypeNode.modifiers);
643732
namespace.ownedElements.push(_annotationType);
644733

734+
// Translate Type Parameters
735+
this.translateTypeParameters(options, _annotationType, annotationTypeNode.typeParameters);
645736
// Translate Types
646737
this.translateTypes(options, _annotationType, annotationTypeNode.body);
647738
// Translate Members
648739
this.translateMembers(options, _annotationType, annotationTypeNode.body);
649740
};
650741

651742
/**
652-
* Translate Java Field Node.
743+
* Translate Java Field Node as UMLAssociation.
653744
* @param {Element} namespace
654745
* @param {Object} fieldNode
655746
*/
656-
JavaAnalyzer.prototype.translateField = function (options, namespace, fieldNode) {
747+
JavaAnalyzer.prototype.translateFieldAsAssociation = function (options, namespace, fieldNode) {
748+
var i, len;
749+
if (fieldNode.variables && fieldNode.variables.length > 0) {
750+
// Add to _associationPendings
751+
this._associationPendings.push({
752+
classifier: namespace,
753+
node: fieldNode
754+
});
755+
}
756+
};
757+
758+
/**
759+
* Translate Java Field Node as UMLAttribute.
760+
* @param {Element} namespace
761+
* @param {Object} fieldNode
762+
*/
763+
JavaAnalyzer.prototype.translateFieldAsAttribute = function (options, namespace, fieldNode) {
657764
var i, len;
658765
if (fieldNode.variables && fieldNode.variables.length > 0) {
659766
for (i = 0, len = fieldNode.variables.length; i < len; i++) {
660767
var variableNode = fieldNode.variables[i];
768+
769+
// Create Attribute
661770
var _attribute = new type.UMLAttribute();
662771
_attribute._parent = namespace;
663772
_attribute.name = variableNode.name;
664773

665774
// Modifiers
666775
_attribute.visibility = this._getVisibility(fieldNode.modifiers);
667-
_attribute.type = this._findType(namespace, fieldNode.type);
668776
if (variableNode.initializer) {
669777
_attribute.defaultValue = variableNode.initializer;
670778
}
@@ -676,9 +784,6 @@ define(function (require, exports, module) {
676784
_attribute.isReadOnly = true;
677785
}
678786
// TODO: volatile, transient
679-
680-
// TODO: Attribute? or Assocation?
681-
682787
namespace.attributes.push(_attribute);
683788

684789
// Add to _typedFeaturePendings
@@ -687,10 +792,12 @@ define(function (require, exports, module) {
687792
feature: _attribute,
688793
node: fieldNode.type
689794
});
795+
690796
}
691797
}
692798
};
693799

800+
694801
/**
695802
* Translate Method
696803
*/
@@ -699,6 +806,7 @@ define(function (require, exports, module) {
699806
_operation = new type.UMLOperation();
700807
_operation._parent = namespace;
701808
_operation.name = methodNode.name;
809+
namespace.operations.push(_operation);
702810

703811
// Modifiers
704812
_operation.visibility = this._getVisibility(methodNode.modifiers);
@@ -739,9 +847,19 @@ define(function (require, exports, module) {
739847
_operation.parameters.push(_returnParam);
740848
}
741849

742-
// TODO: throw exceptions
850+
// Throws
851+
if (methodNode.throws) {
852+
for (i = 0, len = methodNode.throws.length; i < len; i++) {
853+
var _throwNode = methodNode.throws[i];
854+
this._throwPendings.push({
855+
operation: _operation,
856+
node: _throwNode
857+
});
858+
}
859+
}
743860

744-
namespace.operations.push(_operation);
861+
// Translate Type Parameters
862+
this.translateTypeParameters(options, _operation, methodNode.typeParameters);
745863
};
746864

747865
/**

grammar/java7.jison

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,31 @@ typeParameters
261261
{
262262
$$ = [];
263263
if ($1[0] === "<" && $1[$1.length-1] === ">") {
264-
var i, _temp;
264+
var i, _temp, _param, _bounded;
265265
$1 = $1.substring(1, $1.length-1);
266266
_temp = $1.split(",");
267267
for (i = 0; i < _temp.length; i++) {
268-
$$.push(_temp[i].trim());
268+
_param = _temp[i].trim();
269+
if (_param.indexOf(" extends ") > 0) {
270+
_bounded = _param.split("extends");
271+
if (_bounded.length > 1) {
272+
$$.push({
273+
"node": "TypeParameter",
274+
"name": _bounded[0].trim(),
275+
"type": _bounded[1].trim()
276+
});
277+
} else {
278+
$$.push({
279+
"node": "TypeParameter",
280+
"name": _param
281+
});
282+
}
283+
} else {
284+
$$.push({
285+
"node": "TypeParameter",
286+
"name": _param
287+
});
288+
}
269289
}
270290
}
271291
}

grammar/java7.js

Lines changed: 22 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ define(function (require, exports, module) {
173173
if (!err) {
174174
if (files && files.length > 0) {
175175
var options = {
176+
association: true,
176177
path: files[0]
177178
};
178179
JavaReverseEngineer.analyze(options).then(result.resolve, result.reject);
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.mycompany.test;
22

33
// Generic Class
4-
public class GenericClassTest<E, T> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
4+
public class GenericClassTest<E, T extends java.util.Collection> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
55

66
// Field
77
private OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>());
8+
private ClassTest classTestRef;
89

910
// Constructor and Method
10-
public Vector(Collection<? extends E> c) {}
11+
public GenericClassTest(Collection<? extends E> c) {}
1112
public Enumeration<E> elements() {}
12-
13+
public <T extends Product> void printAll(ArrayList<T> list) {}
1314
}

0 commit comments

Comments
 (0)