Distinguish between lightweight and annotated tags in JGit - jgit

I'm trying to figure out how to distinguish between lightweight and annotated tags in JGit without catching any exceptions. In my special case, I need that distinction for getting all tag names of a given commit.
public List<String> getTagNamesOfCommit(String commitHash) throws Exception {
List<String> tagNames = new ArrayList<>();
RevWalk walk = new RevWalk(repository);
List<Ref> tagList = git.tagList().call();
for (Ref tag : tagList) {
ObjectId peeledObjectId = tag.getPeeledObjectId();
try {
// Try to get annotated tag
RevTag refetchedTag = walk.parseTag(tag.getObjectId());
RevObject peeled = walk.peel(refetchedTag.getObject());
if (peeled.getId().getName().equals(commitHash)) {
tagNames.add(Repository.shortenRefName(tag.getName()));
}
} catch(IncorrectObjectTypeException notAnAnnotatedTag) {
// Tag is not annotated. Yes, that's how you find out ...
if (tag.getObjectId().getName().equals(commitHash)) {
tagNames.add(Repository.shortenRefName(tag.getName()));
}
}
}
walk.close();
return tagNames;
}
This is an equivalent solution as contained in an answer to this question
RevTag tag;
try {
tag = revWalk.parseTag(ref.getObjectId());
// ref points to an annotated tag
} catch(IncorrectObjectTypeException notAnAnnotatedTag) {
// ref is a lightweight (aka unannotated) tag
}
The class org.eclipse.jgit.lib.Ref has the method getPeeledObjectId() which should return the id of the commit in case of an annotated tag.
* return if this ref is an annotated tag the id of the commit (or tree or
* blob) that the annotated tag refers to; {#code null} if this ref
* does not refer to an annotated tag.
This way I could check for null, which is much nicer than catching an exception. Unfortunately the method returns null in every case.
Two questions:
Is there anything wrong with the use of git.tagList().call()?
What would be the correct way to find out if a tag is an annotated one?

If you run the example ReadTagForName in the jgit-cookbook the output contains the following:
Commit: (class org.eclipse.jgit.revwalk.RevCommit)commit a3033aec313556ba4e1ef55a66167a35432a4bc1 1369660983 ------p
Tag: (class org.eclipse.jgit.revwalk.RevTag)tag 25f629b5e8ddfabd55650c05ffbb5199633b6df0 ------p
So you should be able to check for the actual class of the Ref object that is returned. If it is "RevCommit" it is a lightweight tag, and if it is "RevTag" it seems to be an annotated tag.

Related

Access Kotlin Delegate Type without an Instance

I have read Access property delegate in Kotlin which is about accessing a delegate from an instance. One can use KProperty::getDelegate since Kotlin 1.1, however this will return the instance of the delegate and therefore needs an instance of the class first.
Now I want to get the type of the delegate without having an instance of the class. Consider a library with a custom delegate type CustomDelegate that want's to get all properties of a class that are delegated to an instance of CustomDelegate:
class Example
{
var nonDelegatedProperty = "I don't care about this property"
var delegatedProperty1 by lazy { "I don't care about this too" }
var delegatedProperty2 by CustomDelegate("I care about this one")
}
How can I, given I have KClass<Example>, but not an instance of Example, get all properties delegated to CustomDelegate?
How can I, given I have KClass<Example>, but not an instance of
Example, get all properties delegated to CustomDelegate?
You can do it in two ways depending on your needs.
First of all, you have to include the kotlin-reflect dependency in your build.gradle file:
compile "org.jetbrains.kotlin:kotlin-reflect:1.1.51"
In my opinion, you should use the first solution if you can, because it's the most clear and optimized one. The second solution instead, can handle one case that the first solution can't.
First
You can loop an the declared properties and check if the type of the property or the type of the delegate is CustomDelegate.
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
// If the type of field is CustomDelegate or the delegate is an instance of CustomDelegate,
// it will return true.
CustomDelegate::class.java == property.javaField?.type
}
There's only one problem with this solution, you will get also the fields with type CustomDelegate, so, given this example:
class Example {
var nonDelegatedProperty = "I don't care about this property"
val delegatedProperty1 by lazy { "I don't care about this too" }
val delegatedProperty2 by CustomDelegate("I care about this one")
val customDelegate = CustomDelegate("jdo")
}
You will get delegatedProperty2 and customDelegate. If you want to get only delegatedProperty2, I found an horrible solution that you can use if you need to manage this case.
Second
If you check the source code of KPropertyImpl, you can see how a delegation is implemented. So, you can do something like this:
// Loop on the properties of this class.
Example::class.declaredMemberProperties.filter { property ->
// You must check in all superclasses till you find the right method.
property::class.allSuperclasses.find {
val computeField = try {
// Find the protected method "computeDelegateField".
it.declaredFunctions.find { it.name == "computeDelegateField" } ?: return#find false
} catch (t: Throwable) {
// Catch KotlinReflectionInternalError.
return#find false
}
// Get the delegate or null if the delegate is not present.
val delegateField = computeField.call(property) as? Field
// If the delegate was null or the type is different from CustomDelegate, it will return false.
CustomDelegate::class.java == delegateField?.type
} != null
}
In this case, you will get only delegatedProperty2 as result.

Multiplicity constraint violated. The role '...' of the relationship '...' has multiplicity 1 or 0..1

I'm getting the following error from my DbContext: "Multiplicity constraint violated. The role 'MyEntity' of the relationship 'MyModel.FK_ChildEntities_MyEntities' has multiplicity 1 or 0..1."
using ASP.NET, Entity Framework 4
Working with a detached entity
The error happens the second time I try to reattach an entity to the dbcontext. The scenario is an unsuccessful save followed by a reattempt.
I have a detached entity in session. The user changes properties in a form, add things, removes things and finally clicks save. I get an attached copy of the entity from a new instance of the dbcontext, apply changes from the detached entity to the attached entity, validate, find an error and abort. The user changes whatever and saves again.
On the second save, the whole save process repeats, only this time it all goes to hell. Pretty much everything is duplicated, causing one error or another or all of them. Values from views and lookup tables that are only supposed to be references are created new and reassigned id's. Most of those issues I've been able to resolve, but I'm left with the multiplicity error. Child elements are being created as exact copies of other child elements, down to the unique id, only in the Added state. Or, if I reference certain properties, instead of cloning an unmodified child, it drops the new one. Either way, none of the code is executing as it did the first time around.
I'm discarding the instance of the dbcontext and the attached entity each save attempt. I thought that would be enough to revert any changes but something must be sticking around. The only thing not discared or reset is the detached entity, which is in session, but I dont make any changes to it. At least not directly.
The code (very simplified) is something like this:
void Save()
{
using (var context = new MyContext())
{
// detached entity from session
MyEntity detachedEntity = (MyEntity)Session["DetachedEntity"];
// attached entity from context
MyEntity attachedEntity = context.MyEntities.Single(x=>x.id == detachedEntity.id);
// <remove children representing lookup table elements from detachedEntity to prevent duplicates>
// <remove children representing view elements from detachedEntity to prevent duplicates>
// <apply changes from detachedEntity to attachedEntity>
// <add new children>
// <remove deleted children>
// <update modified children>
// <set entity state to unchanged on view and lookup elements of attachedEntity to ensure no duplicates...>
// <validate>
if (errors.count>0)
// <report errors>
else
context.SaveChanges();
}
}
as an example, this generates a multiplicity error:
// represents first save:
using (var context = new MyContext())
{
// detached entity from session
MyEntity detachedEntity = (MyEntity)Session["DetachedEntity"];
// attached entity from context
MyEntity attachedEntity = context.MyEntities.Single(x=>x.id == detachedEntity.id);
int debug1 = context.ChangeTracker.Entries<ChildEntity>().Count(); // debug1 == 0;
attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First());
int debug2 = context.ChangeTracker.Entries<ChildEntity>().Count(); // debug2 == 1;
}
// represents second save:
using (var context = new MyContext())
{
// detached entity from session
MyEntity detachedEntity = (MyEntity)Session["DetachedEntity"];
// attached entity from context
MyEntity attachedEntity = context.MyEntities.Single(x=>x.id == detachedEntity.id);
int debug1 = context.ChangeTracker.Entries<ChildEntity>().Count(); // debug1 == 0;
attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First());
int debug2 = context.ChangeTracker.Entries<ChildEntity>().Count(); // multiplicity error;
}
somehow the dbcontext remembers what objects were added to it. if the exact same object shows up twice, it... blows
instead of adding child entities from my detached entity to the attached one, i should've been creating new copies of each child
ChildEntity detachedChild = detachedEntity.ChildEntities.First();
attachedEntity.ChildEntities.Add(new ChildEntity {
propertyA = detachedChild.propertyA,
propertyB = detachedChild.propertyB
});
instead of
attachedEntity.ChildEntities.Add(detachedEntity.ChildEntities.First());
The problem is that detachedChild.parent should be assigned attachedParent.
foreach(var detachedEntity in detachedEntities)
{
attachedEntity.ChildEntities.Add(detachedEntity);
detachedEntity.ParentEntity = attachedEntity;
}
What you are trying to do is something like:
ChildEntity childEntity = new ChildEntity()
{
//do mapping or provide data EXCEPt THE PRIMARY KEY
}
foreach(ParentEntity parentEntity in parentEntities)
{
parentEntity.Add(childEntity);
}
_dbContext.SaveChanges();
Result
Multiplicity constraint violated. The role '…' of the relationship '…' has multiplicity 1 or 0..1
The reason of the error message is
that everytime the _dbContext adds the childEntity to some parentEntity, it sets the generated primary key to the childEntity, so in the second loop of the foreach the primary key will be duplicated
The fix is - Method #1 - for simple scenarios
foreach(ParentEntity parentEntity in parentEntities)
{
//Make a new object every time
ChildEntity childEntity = new ChildEntity()
{
//do mapping or provide data EXCEPt THE PRIMARY KEY
}
parentEntity.Add(childEntity);
}
_dbContext.SaveChanges();
The fix is - Method #2 - for complex scenarios
using YOUR_PROJECT.ANY_FOLDER.DeepCopyExtensions;
ChildEntity childEntity = new ChildEntity()
{
//do mapping or provide data EXCEPt THE PRIMARY KEY
}
foreach(ParentEntity parentEntity in parentEntities)
{
//makes a copy of the childEntity object and pass it to the _dbContext, after saving each copy will be separated and the original object childEntity wont be touched
parentEntity.Add(DeepCopyByExpressionTrees.DeepCopyByExpressionTree(childEntity));
}
_dbContext.SaveChanges();
What is this method "DeepCopyByExpressionTrees.DeepCopyByExpressionTree(childEntity)" ?
Check this project here, download the source code, and only include the class file "DeepCopyByExpressionTrees.cs" to your project as a helper class and start using it any where.
Thanks
Make sure to inspect the properties of the object you are trying to add. In my case it was mistakenly referencing the same invalid object on each add which it didn't like and thus threw the same error you have here.
EF 6 Update
For me setting object state to added worked on sounds logical also
ChildEntity detachedChild = detachedEntity.ChildEntities.First();
var newChild = new ChildEntity {
propertyA = detachedChild.propertyA,
propertyB = detachedChild.propertyB
});
// Mark all added entity entity state to Added
attachedEntity.ChildEntities.Add(newChild );
db.Entry(newChild ).State = EntityState.Added;
http://www.entityframeworktutorial.net/EntityFramework4.3/update-one-to-many-entity-using-dbcontext.aspx
I experienced this error when I had navigation properties that had not been set or navigation properties that belonged to the wrong Code First DBContext
I fixed this by making the child collections in the parent entity virtual. This allows one to easily Update the entity when its child collections don't change, which, for me, was most of the time.
I had a similar issue, but mine arose from a AsNoTracking() after my query.
I had something like this
var myObject = dbContext.GetRepo<myType>().Query().AsNoTracking().SingleOrDefault()
And then later on I use that object to set anther object.
var myChild = new Child { parent = myObect }
and apparently EntityFramework tries to create a brand new object and hence causes a multiplicity error.

Inheritance and the JSON formatter of ASP.NET Web API

Imagine a simple controller action IEnumerable<BaseType> Get(). It returns an enumeration of different types all deriving from BaseType.
When the client requests XML, the result is something like this:
<ArrayOfBaseType>
<BaseType i:type="DerivedType1"><A>value</A></BaseType>
<BaseType i:type="DerivedType2"><B>value</B></BaseType>
<BaseType i:type="DerivedType3"><C>value</C></BaseType>
</ArrayOfBaseType>
As you can see, the type of the derived class is transmitted in the i:type attribute.
If the client requests JSON however, this information is missing:
[
{"A":"value"},
{"B":"value"},
{"C":"value"}
]
How to fix this?
The following change is necessary:
In the WebApiConfig.cs the following line needs to be added:
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling =
TypeNameHandling.Auto;
This will automatically result in a new property $type when needed.
If you write your class following:
public class MyClass
{
// properties here
public string IType
{
get
{
return this.GetType().Name;
}
set { }
}
}
Maybe, it will help you

How to check if a variable exists in flex

In flex, how to check if a variable exists? I have tried using
if (this['some_variable'] != undefined) {
//do something
}
There is a run time error saying the property some_variable does not exists. I have checked with null instead of undefined, still the same error.
please help.
[EDIT]
Based on the replies I have used this.hasOwnProperty('variable_name'). I found that its returning true if variable_name is a public but false if its private/protected. How to check for a private variable?
There are two ways for that:
if ("some_variable" in this) {
//do something
}
It uses in operator.
And:
if (this.hasOwnProperty("some_variable")) {
//do something
}
See documentation about hasOwnProperty().
What about getting information about private/protected properties the situation is that you can't get this info with the current state of Flash Player. The only possible way, I suppose, is some kind of runtime bytecode manipulation. But as far as I know nobody implemented it yet.
But I have a question about getting info about private/protected properties: for what purpose you need it? The nature of these properties/methods is you can't call them. Even if you know about their existence.
You can use
if (this. hasOwnProperty("some_variable")) {
//access the variable inside
}
if (this.hasOwnProperty('some_variable')) DO_IT_!()
Explanation:
this['some_variable'] tries to evaluate the value of the instance property some_variable. If there is no such a property, you will get this error.
To test if a property exists for a particular object use hasOwnProperty or wrap your condition in a try/catch block or use if ('some_variable' in this).
Usually you create an object property in a class file:
public class MyClass {
public var myProperty : String = "ich bin hier";
}
Then you refer to that property within the class:
trace (myProperty);
trace (this.myProperty);
Using the array syntax [] is also possible but will throw the error if the property is not defined.
trace (this['myProperty']);
And finally! If you declare your class to be dynamic you might use the array syntax even if the property does not exist.
public dynamic class MyClass {
public function MyClass() {
trace (this["never_declared_property"]);
}
}

Why some VariableDeclaration resolveBinding returns null but others does not

I am developing an eclipse plug-in to analyze the java source code. I traverse the whole AST tree and write a visitor to visit each variableDeclartionStatement, I noticed for some variables, the "resolvebinding" return an instance of IVariableBinding, but others does not. I can not differentiate them. BTW: I have set the ASTParser.setKind(K_COMPILATION_UNIT) and setResolveBindings(true). My code is as follows:
#Override
public boolean visit(VariableDeclarationStatement vStatement) {
Type theType = vStatement.getType();
for(Iterator iterator = vStatement.fragments().iterator();iterator.hasNext();){
VariableDeclarationFragment fragment = (VariableDeclarationFragment)iterator.next();
IVariableBinding binding = fragment.resolveBinding();
if(binding !=null){
ITypeBinding tBinding = binding.getType();
if(tBinding !=null){
// if there is ArrayType, get the root type
while(tBinding.getComponentType()!=null){
tBinding = tBinding.getComponentType();
}
System.out.println("USING BINDING VARIABLE CLASS IS: " + tBinding.getQualifiedName());
}
}
}
}
My question is: How can I differentiate the variable declarations which can resolve bindings with others which can not?
Many thanks in advance
From the JavaDoc on VariableDeclarationFragment:
Variable declaration fragment AST node
type, used in field declarations,
local variable declarations, and
ForStatement initializers. It
contrast to
SingleVariableDeclaration, fragments
are missing the modifiers and the
type; these are located in the
fragment's parent node.
Try to get the type binding from the VariableDeclarationFragment's parent.

Resources