Java tutorial
/******************************************************************************* * <copyright> * * Copyright (c) 2005, 2012 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Stefan Dimov - initial API, implementation and documentation * * </copyright> * *******************************************************************************/ package org.eclipse.jpt.jpadiagrameditor.ui.internal.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.net.URI; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Locale; import java.util.Properties; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; import org.eclipse.graphiti.mm.algorithms.Image; import org.eclipse.graphiti.mm.algorithms.Rectangle; import org.eclipse.graphiti.mm.algorithms.RoundedRectangle; import org.eclipse.graphiti.mm.algorithms.Text; import org.eclipse.graphiti.mm.pictograms.Anchor; import org.eclipse.graphiti.mm.pictograms.Connection; import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.FreeFormConnection; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.mm.pictograms.Shape; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IImportDeclaration; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.internal.core.search.JavaSearchScope; import org.eclipse.jdt.ui.actions.FormatAllAction; import org.eclipse.jdt.ui.actions.OrganizeImportsAction; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jpt.common.core.resource.java.JavaResourceAttribute; import org.eclipse.jpt.common.core.resource.xml.JptXmlResource; import org.eclipse.jpt.jpa.core.JpaProject; import org.eclipse.jpt.jpa.core.context.AttributeMapping; import org.eclipse.jpt.jpa.core.context.EmbeddedIdMapping; import org.eclipse.jpt.jpa.core.context.EmbeddedMapping; import org.eclipse.jpt.jpa.core.context.IdMapping; import org.eclipse.jpt.jpa.core.context.ManyToManyMapping; import org.eclipse.jpt.jpa.core.context.OneToManyMapping; import org.eclipse.jpt.jpa.core.context.PersistentAttribute; import org.eclipse.jpt.jpa.core.context.PersistentType; import org.eclipse.jpt.jpa.core.context.TransientMapping; import org.eclipse.jpt.jpa.core.context.VersionMapping; import org.eclipse.jpt.jpa.core.context.persistence.ClassRef; import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit; import org.eclipse.jpt.jpa.core.jpa2.context.DerivedIdentity2_0; import org.eclipse.jpt.jpa.core.jpa2.context.ElementCollectionMapping2_0; import org.eclipse.jpt.jpa.core.jpa2.context.ManyToOneMapping2_0; import org.eclipse.jpt.jpa.core.jpa2.context.OneToOneMapping2_0; import org.eclipse.jpt.jpa.core.resource.persistence.PersistenceFactory; import org.eclipse.jpt.jpa.core.resource.persistence.XmlJavaClassRef; import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistence; import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistenceUnit; import org.eclipse.jpt.jpadiagrameditor.ui.internal.JPADiagramEditorPlugin; import org.eclipse.jpt.jpadiagrameditor.ui.internal.facade.EclipseFacade; import org.eclipse.jpt.jpadiagrameditor.ui.internal.i18n.JPAEditorMessages; import org.eclipse.jpt.jpadiagrameditor.ui.internal.propertypage.JPADiagramPropertyPage; import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorFeatureProvider; import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorImageCreator.RelEndDir; import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.JPAEditorImageProvider; import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.HasReferanceRelation; import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.IRelation; import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.IsARelation; import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorConstants.ShapeType; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbenchSite; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.wst.common.project.facet.core.IFacetedProject; import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion; import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager; @SuppressWarnings("restriction") public class JPAEditorUtil { public static final String JPA_PROJECT_FACET_10 = "1.0"; //$NON-NLS-1$ private static IPeServiceUtil peUtil = null; private final static String PERSISTENCE_PROVIDER_LIBRARY_STRING = "javax/persistence/"; //$NON-NLS-1$ public static String capitalizeFirstLetter(String s) { if (s.length() == 0) return s; String res = s.substring(0, 1).toUpperCase(Locale.ENGLISH) + s.substring(1); return res; } public static String decapitalizeFirstLetter(String s) { if (s.length() == 0) return s; String res = s.substring(0, 1).toLowerCase(Locale.ENGLISH) + s.substring(1); return res; } public static String revertFirstLetterCase(String s) { if ((s == null) || (s.length() == 0)) return s; return (Character.isLowerCase(s.charAt(0)) ? s.substring(0, 1).toUpperCase(Locale.ENGLISH) : s.substring(0, 1).toLowerCase(Locale.ENGLISH)) + s.substring(1); } synchronized public static IPeServiceUtil getPeUtil() { if (peUtil == null) peUtil = new PeServiceUtilImpl(); return peUtil; } private static Anchor getAnchor(ContainerShape cs) { Collection<Anchor> anchors = cs.getAnchors(); if (anchors.iterator().hasNext()) return anchors.iterator().next(); return null; } public static Anchor getAnchor(PersistentType jpt, IFeatureProvider fp) { PictogramElement pe = fp.getPictogramElementForBusinessObject(jpt); if ((pe == null) || (!(pe instanceof ContainerShape))) return null; return getAnchor((ContainerShape) pe); } public static String getText(PersistentAttribute at) { return at.getName(); } public static String returnSimpleName(String s) { return s.substring(s.lastIndexOf('.') + 1); } public static String stripQuotes(String s) { if ((s.startsWith("\"")) && (s.endsWith("\""))) //$NON-NLS-1$ //$NON-NLS-2$ return s.substring(1, s.length() - 1); return s; } public static String getTooltipText(PersistentType jpt, String superPersistentTypeName) { String res = jpt.getName(); if (superPersistentTypeName != null) { return MessageFormat.format(JPAEditorMessages.JPAEditorUtil_inheritTypeTooltipText, new Object[] { res, superPersistentTypeName }); } return MessageFormat.format(JPAEditorMessages.JPAEditorUtil_fullnameTooltipText, new Object[] { res }); } public static String getAttributeTypeName(PersistentAttribute at) { return JpaArtifactFactory.instance().getRelTypeName(at); } public static String getAttributeTypeName(JavaResourceAttribute at) { return at.getTypeBinding().getQualifiedName(); } public static String getAttributeTypeNameWithGenerics(PersistentAttribute at) { return getAttributeTypeNameWithGenerics(at.getJavaPersistentAttribute().getResourceAttribute()); } private static String getAttributeTypeNameWithGenerics(JavaResourceAttribute at) { StringBuilder res = new StringBuilder(getAttributeTypeName(at)); ListIterator<String> it = at.getTypeBinding().getTypeArgumentNames().iterator(); if ((it != null) && it.hasNext()) { res.append('<'); res.append(createCommaSeparatedListOfFullTypeNames(it)); res.append('>'); } return res.toString(); } public static String[] getGenericsElementTypes(String typeName) { if (typeName.indexOf("<") == -1) //$NON-NLS-1$ return null; String types = typeName.substring(typeName.indexOf("<") + 1, typeName.lastIndexOf(">")); //$NON-NLS-1$ //$NON-NLS-2$ String[] typeNames = types.split(","); //$NON-NLS-1$ for (int i = 0; i < typeNames.length; i++) { typeNames[i] = typeNames[i].trim(); } return typeNames; } public static String createCommaSeparatedListOfSimpleTypeNames(String[] strings) { if ((strings == null) || (strings.length == 0)) return null; StringBuilder res = new StringBuilder(JPAEditorUtil.returnSimpleName(strings[0])); for (int i = 1; i < strings.length; i++) { res.append(", "); //$NON-NLS-1$ res.append(JPAEditorUtil.returnSimpleName(strings[i])); } return res.toString(); } private static String createCommaSeparatedListOfFullTypeNames(ListIterator<String> strIt) { if ((strIt == null) || !strIt.hasNext()) return null; StringBuilder res = new StringBuilder(strIt.next()); while (strIt.hasNext()) { res.append(", "); //$NON-NLS-1$ res.append(strIt.next()); } return res.toString(); } public static String getText(PersistentType jpt) { return JPAEditorUtil.returnSimpleName(JpaArtifactFactory.instance().getEntityName(jpt)); } public static String getTooltipText(PersistentType jpt) { String res = jpt.getName(); return MessageFormat.format(JPAEditorMessages.JPAEditorUtil_fullnameTooltipText, new Object[] { res }); } public static PersistentType getJPType(ICompilationUnit cu) { String name = cu.getElementName(); if (!name.endsWith(".java")) //$NON-NLS-1$ return null; IType tp = cu.findPrimaryType(); if (tp == null) return null; name = tp.getFullyQualifiedName(); IJavaProject jp = cu.getJavaProject(); JpaProject proj = null; proj = JpaArtifactFactory.instance().getJpaProject(jp.getProject()); if (proj == null) return null; PersistenceUnit pu = JpaArtifactFactory.instance().getPersistenceUnit(proj); PersistentType pt = pu.getPersistentType(name); if (pt == null) { pt = JpaArtifactFactory.instance().getJPT(name, pu); } return pt; } public static PersistentType findJpt(IType type) { String name = type.getFullyQualifiedName(); IJavaProject jp = type.getJavaProject(); JpaProject proj = null; proj = JpaArtifactFactory.instance().getJpaProject(jp.getProject()); if (proj == null) return null; PersistenceUnit pu = JpaArtifactFactory.instance().getPersistenceUnit(proj); PersistentType pt = pu.getPersistentType(name); if (pt == null) { pt = JpaArtifactFactory.instance().getJPT(name, pu); } return pt; } public static void setJPTNameInShape(ContainerShape cs, String newName) { setJPTNameInShape(cs, newName, getPeUtil()); } public static void setJPTNameInShape(ContainerShape cs, String newName, IPeServiceUtil peUtil) { List<Shape> shapes = cs.getChildren(); Iterator<Shape> it = shapes.iterator(); while (it.hasNext()) { Shape sh = it.next(); String propShapeType = peUtil.getPropertyValue(sh, JPAEditorConstants.PROP_SHAPE_TYPE); if (!ShapeType.HEADER.toString().equals(propShapeType)) continue; Text txt = (Text) sh.getGraphicsAlgorithm().getGraphicsAlgorithmChildren().get(0); txt.setValue(newName); return; } } public static String produceValidAttributeName(String name) { if ((name == null) || (name.length() == 0)) return ""; //$NON-NLS-1$ if (name.length() == 1) return name.toLowerCase(Locale.ENGLISH); String secondSymbol = name.substring(1, 2); if (secondSymbol.toLowerCase(Locale.ENGLISH).equals(secondSymbol.toUpperCase(Locale.ENGLISH))) return decapitalizeFirstLetter(name); return (isUpperCase(secondSymbol)) ? capitalizeFirstLetter(name) : decapitalizeFirstLetter(name); } private static boolean isUpperCase(String s) { if ((s == null) || (s.length() == 0) || (s.length() > 1)) throw new IllegalArgumentException("The given string has to contain one symbol exactly"); //$NON-NLS-1$ return s.toUpperCase(Locale.ENGLISH).equals(s); } public static void createRegisterEntityInXMLJob(final JpaProject jpaProject, final String classFQN) { final JptXmlResource resource = jpaProject.getPersistenceXmlResource(); XmlPersistence xmlPersistence = (XmlPersistence) resource.getRootObject(); EList<XmlPersistenceUnit> persistenceUnits = xmlPersistence.getPersistenceUnits(); XmlPersistenceUnit persistenceUnit = persistenceUnits.get(0); // Multiply persistence unit support boolean registered = false; for (XmlJavaClassRef ref : persistenceUnit.getClasses()) { String className = ref.getJavaClass(); if (classFQN.equals(className)) { registered = true; break; } } if (!registered) { XmlJavaClassRef classRef = PersistenceFactory.eINSTANCE.createXmlJavaClassRef(); classRef.setJavaClass(classFQN); persistenceUnit.getClasses().add(classRef); } resource.save(); } public static void createUnregisterEntityFromXMLJob(final JpaProject jpaProject, final String classFQN) { JptXmlResource resource = jpaProject.getPersistenceXmlResource(); XmlPersistence xmlPersistence = (XmlPersistence) resource.getRootObject(); EList<XmlPersistenceUnit> persistenceUnits = xmlPersistence.getPersistenceUnits(); XmlPersistenceUnit persistenceUnit = persistenceUnits.get(0);// Multiply persistence unit support EList<XmlJavaClassRef> cRefs = persistenceUnit.getClasses(); for (XmlJavaClassRef ref : cRefs) { if (ref.getJavaClass().equals(classFQN)) { cRefs.remove(ref); break; } } resource.save(); } public static void createImports(ICompilationUnit cu, String typeFQN) { if (typeFQN == null) return; typeFQN = typeFQN.trim(); String[] typeFQNs = getAllTypes(typeFQN); createImports(cu, typeFQNs); } private static String[] getAllTypes(String typeFQN) { typeFQN = typeFQN.replace('[', ','); typeFQN = typeFQN.replace(']', ','); typeFQN = typeFQN.replace('<', ','); typeFQN = typeFQN.replace('>', ','); String[] res = typeFQN.trim().split(","); //$NON-NLS-1$ for (int i = 0; i < res.length; i++) res[i] = res[i].trim(); return res; } public static void createImports(ICompilationUnit cu, String[] typeFQNs) { NullProgressMonitor npm = new NullProgressMonitor(); for (String typeFQN : typeFQNs) { if (typeFQN.startsWith("java.lang.") || !typeFQN.contains(".")) //$NON-NLS-1$ //$NON-NLS-2$ continue; try { cu.createImport(typeFQN, null, npm); } catch (JavaModelException e) { } } } public static String createImport(ICompilationUnit cu, String typeFQN) { if (typeFQN.startsWith("java.lang.") || !typeFQN.contains(".")) //$NON-NLS-1$ //$NON-NLS-2$ return returnSimpleName(typeFQN); NullProgressMonitor npm = new NullProgressMonitor(); String simpleName = returnSimpleName(typeFQN); IImportDeclaration[] ids = new IImportDeclaration[0]; try { ids = cu.getImports(); } catch (JavaModelException e) { } for (IImportDeclaration id : ids) { String impName = id.getElementName(); if (impName.endsWith("*")) //$NON-NLS-1$ continue; if (impName.endsWith("." + simpleName)) //$NON-NLS-1$ return typeFQN; if (JPAEditorConstants.WRAPPER_SIMPLE_NAMES.contains(simpleName)) return typeFQN; } try { cu.createImport(typeFQN, null, npm); return returnSimpleName(typeFQN); } catch (JavaModelException e) { } return typeFQN; } public static Image createAttributeIcon(Rectangle iconRect, AttributeMapping attributeMapping) { Image icon = null; if (attributeMapping instanceof IdMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.PRIMARY_KEY); } else if (attributeMapping instanceof OneToOneMapping2_0) { DerivedIdentity2_0 ident = ((OneToOneMapping2_0) attributeMapping).getDerivedIdentity(); if (ident.usesIdDerivedIdentityStrategy() || ident.usesMapsIdDerivedIdentityStrategy()) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ONE_TO_ONE_PRIMARY_KEY); } else { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_ONE_TO_ONE); } } else if (attributeMapping instanceof OneToManyMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_ONE_TO_MANY); } else if (attributeMapping instanceof ManyToOneMapping2_0) { DerivedIdentity2_0 ident = ((ManyToOneMapping2_0) attributeMapping).getDerivedIdentity(); if (ident.usesIdDerivedIdentityStrategy() || ident.usesMapsIdDerivedIdentityStrategy()) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.MANY_TO_ONE_PRIMARY_KEY); } else { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_MANY_TO_ONE); } } else if (attributeMapping instanceof ManyToManyMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_MANY_TO_MANY); } else if (attributeMapping instanceof EmbeddedIdMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_EMBEDDED_ID); } else if (attributeMapping instanceof VersionMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_VERSION); } else if (attributeMapping instanceof TransientMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_TRANSIENT); } else if (attributeMapping instanceof EmbeddedMapping) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_EMBEDDED); } else if (attributeMapping instanceof ElementCollectionMapping2_0) { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_ELEMENT_COLLECTION); } else { icon = Graphiti.getGaService().createImage(iconRect, JPAEditorImageProvider.ICON_BASIC); } return icon; } public static Collection<ContainerShape> getRelatedShapes(ContainerShape cs) { Collection<ContainerShape> res = new HashSet<ContainerShape>(); Collection<Connection> cons = new HashSet<Connection>(); Iterator<Anchor> ansIt = cs.getAnchors().iterator(); while (ansIt.hasNext()) { Anchor an = ansIt.next(); cons.addAll(an.getIncomingConnections()); cons.addAll(an.getOutgoingConnections()); } Iterator<Connection> consIt = cons.iterator(); while (consIt.hasNext()) { Connection con = consIt.next(); ContainerShape cs1 = null; try { cs1 = (ContainerShape) con.getStart().getParent(); } catch (NullPointerException e) { continue; } if (cs1 != cs) res.add(cs1); cs1 = (ContainerShape) con.getEnd().getParent(); if (cs1 != cs) res.add(cs1); } return res; } public static int calcConnectionLength(FreeFormConnection c) { List<org.eclipse.graphiti.mm.algorithms.styles.Point> pts = c.getBendpoints(); int len = 0; for (int i = 0; i < pts.size() - 1; i++) { len = len + ((pts.get(i).getX() == pts.get(i + 1).getX()) ? Math.abs(pts.get(i).getY() - pts.get(i + 1).getY()) : Math.abs(pts.get(i).getX() - pts.get(i + 1).getX())); } return len; } public static List<Point> createBendPointList(FreeFormConnection c, boolean selfRelation) { int cnt = getNumberOfConnectionsWithSameEndsAs(c); return createBendPointList(c, cnt - 1, cnt, selfRelation); } private static List<Point> createBendPointList(FreeFormConnection c, int cnt, int connectionsNum, boolean selfRelation) { return selfRelation ? createBendPointListForSelfRelation(c, cnt, connectionsNum) : createBendPointListForNonSelfRelation(c, cnt, connectionsNum); } private static List<Point> createBendPointListForSelfRelation(FreeFormConnection c, int cnt, int connectionsNum) { final int ABS_SHIFT = 15; int emptiestQuadrant = getEmptiestQuadrant(c); boolean evenQuadrant = (emptiestQuadrant == 2) || (emptiestQuadrant == 4); RoundedRectangle rect = (RoundedRectangle) c.getStart().getParent().getGraphicsAlgorithm(); float halfWidth = rect.getWidth() / 2.0f; float halfHeight = rect.getHeight() / 2.0f; int centerX = Math.round(halfWidth + rect.getX()); int centerY = Math.round(halfHeight + rect.getY()); boolean startHorizontal = false; boolean endHorizontal = !startHorizontal; int startDirection = ((emptiestQuadrant == 2) || (emptiestQuadrant == 3)) ? 1 : -1; // 1 or -1; 1 for RIGHT/DOWN; -1 for LEFT/UP int endDirection = ((emptiestQuadrant == 1) || (emptiestQuadrant == 2)) ? 1 : -1; int x; int y; if (endHorizontal) { x = centerX + Math.round(halfWidth * endDirection); y = centerY; } else { x = centerX; y = centerY + Math.round(halfHeight * endDirection); } int SHIFT = evenQuadrant ? -ABS_SHIFT * endDirection : ABS_SHIFT * endDirection; Point endPoint = new Point(x + (endHorizontal ? 0 : (cnt * SHIFT)), y + (endHorizontal ? (cnt * SHIFT) : 0)); if (startHorizontal) { x = centerX + Math.round(halfWidth * startDirection); y = centerY; } else { x = centerX; y = centerY + Math.round(halfHeight * startDirection); } SHIFT = evenQuadrant ? -ABS_SHIFT * startDirection : ABS_SHIFT * startDirection; Point startPoint = new Point(x + (startHorizontal ? 0 : (cnt * SHIFT)), y + (startHorizontal ? (cnt * SHIFT) : 0)); // second point List<Point> res = new LinkedList<Point>(); res.add(startPoint); if (startHorizontal) { x = startPoint.x + startDirection * 50 + ((evenQuadrant ? -cnt : cnt) * SHIFT); y = startPoint.y; } else { x = startPoint.x; y = startPoint.y + startDirection * 50 + ((evenQuadrant ? -cnt : cnt) * SHIFT); } res.add(new Point(x, y)); // middle point SHIFT = ABS_SHIFT * endDirection; if (startHorizontal) { y = y + Math.round(halfHeight + 50) * endDirection + (2 * cnt * SHIFT); } else { x = x + Math.round(halfWidth + 50) * endDirection + (2 * cnt * SHIFT); } res.add(new Point(x, y)); // fourth point if (startHorizontal) { x = endPoint.x; } else { y = endPoint.y; } res.add(new Point(x, y)); res.add(endPoint); //------------------ return res; } private static int getEmptiestQuadrant(FreeFormConnection selfRel) { Anchor anchor = selfRel.getStart(); RoundedRectangle primRect = (RoundedRectangle) anchor.getParent().getGraphicsAlgorithm(); Collection<Connection> cons = new HashSet<Connection>(); cons.addAll(anchor.getIncomingConnections()); cons.addAll(anchor.getOutgoingConnections()); Iterator<Connection> it = cons.iterator(); Collection<Anchor> anchors = new HashSet<Anchor>(); while (it.hasNext()) { Connection c = it.next(); Anchor a = c.getStart(); if (a != anchor) anchors.add(a); a = c.getEnd(); if (a != anchor) anchors.add(a); } Iterator<Anchor> itAnchors = anchors.iterator(); float[] quadrantHabitat = new float[5]; while (itAnchors.hasNext()) { Anchor a = itAnchors.next(); RoundedRectangle rect = (RoundedRectangle) a.getParent().getGraphicsAlgorithm(); int q = getQuadrant(primRect, rect); quadrantHabitat[q] += 1.5f; if (q == 1) { quadrantHabitat[4] = quadrantHabitat[4] + 0.5f; } else if (q == 4) { quadrantHabitat[1] += 0.5f; } if (q < 4) { quadrantHabitat[q + 1] += 0.5f; } if (q > 1) { quadrantHabitat[q - 1] += 0.5f; } } float minHabitat = Float.MAX_VALUE; int emptiestQuadrant = 0; for (int i = 1; i < 5; i++) { if (quadrantHabitat[i] < minHabitat) { emptiestQuadrant = i; minHabitat = quadrantHabitat[i]; } } return emptiestQuadrant; } private static int getQuadrant(RoundedRectangle primRect, RoundedRectangle rect) { int primCenterX = primRect.getX() + Math.round(primRect.getWidth() / 2.0f); int primCenterY = primRect.getY() + Math.round(primRect.getHeight() / 2.0f); int centerX = rect.getX() + Math.round(rect.getWidth() / 2.0f); int centerY = rect.getY() + Math.round(rect.getHeight() / 2.0f); if (primCenterX < centerX) if (primCenterY > centerY) return 1; else return 2; else if (primCenterY > centerY) return 4; else return 3; } private static List<Point> createBendPointListForNonSelfRelation(FreeFormConnection c, int cnt, int connectionsNum) { final int ABS_SHIFT = 15; RoundedRectangle rectStart = (RoundedRectangle) c.getStart().getParent().getGraphicsAlgorithm(); RoundedRectangle rectEnd = (RoundedRectangle) c.getEnd().getParent().getGraphicsAlgorithm(); float startHalfWidth = rectStart.getWidth() / 2.0f; float startHalfHeight = rectStart.getHeight() / 2.0f; float endHalfWidth = rectEnd.getWidth() / 2.0f; float endHalfHeight = rectEnd.getHeight() / 2.0f; int startCenterX = Math.round(startHalfWidth + rectStart.getX()); int startCenterY = Math.round(startHalfHeight + rectStart.getY()); int endCenterX = Math.round(endHalfWidth + rectEnd.getX()); int endCenterY = Math.round(endHalfHeight + rectEnd.getY()); int xDelta = endCenterX - startCenterX; int yDelta = endCenterY - startCenterY; boolean startHorizontal = true; int x; int y; if (xDelta != 0) { x = startCenterX + Math.round(startHalfWidth * Math.signum(xDelta)); y = startCenterY + Math.round(Math.abs(startHalfWidth / xDelta) * yDelta); } else { x = startCenterX + Math.round(Math.abs(startHalfHeight / yDelta) * xDelta); y = startCenterY + Math.round(startHalfHeight * Math.signum(yDelta)); } if (Math.abs(y - startCenterY) + 0.1 > startHalfHeight) { startHorizontal = false; x = startCenterX + Math.round(Math.abs(startHalfHeight / yDelta) * xDelta); y = startCenterY + Math.round(startHalfHeight * Math.signum(yDelta)); } int SHIFT; if (startHorizontal) { SHIFT = (y < startCenterY) ? ABS_SHIFT : -ABS_SHIFT; } else { SHIFT = (x < startCenterX) ? ABS_SHIFT : -ABS_SHIFT; } Point startPoint = new Point(x + (startHorizontal ? 0 : (cnt * SHIFT)), y + (startHorizontal ? (cnt * SHIFT) : 0)); List<Point> res = new LinkedList<Point>(); xDelta = startCenterX - endCenterX; yDelta = startCenterY - endCenterY; boolean straight = (xDelta == 0) || (yDelta == 0); res.add(startPoint); boolean endHorizontal = true; if (xDelta != 0) { x = endCenterX + Math.round(endHalfWidth * Math.signum(xDelta)); y = endCenterY + Math.round(Math.abs(endHalfWidth / xDelta) * yDelta); } else { x = endCenterX + Math.round(Math.abs(endHalfHeight / yDelta) * xDelta); y = endCenterY + Math.round(endHalfHeight * Math.signum(yDelta)); } if (Math.abs(y - endCenterY) + 0.1 > endHalfHeight) { endHorizontal = false; x = endCenterX + Math.round(Math.abs(endHalfHeight / yDelta) * xDelta); y = endCenterY + Math.round(endHalfHeight * Math.signum(yDelta)); } if (endHorizontal) { SHIFT = (y < endCenterY) ? ABS_SHIFT : -ABS_SHIFT; } else { SHIFT = (x < endCenterX) ? ABS_SHIFT : -ABS_SHIFT; } Point endPoint = new Point(x + (endHorizontal ? 0 : (cnt * SHIFT)), y + (endHorizontal ? (cnt * SHIFT) : 0)); if (!straight) { if (startHorizontal && endHorizontal) { if (startPoint.y != endPoint.y) { x = startPoint.x + Math.round((endPoint.x - startPoint.x) / 2.0f) + cnt * ABS_SHIFT; Point p = new Point(x, startPoint.y); res.add(p); p = new Point(x, endPoint.y); res.add(p); } } else if (!startHorizontal && !endHorizontal) { if (startPoint.x != endPoint.x) { y = startPoint.y + Math.round((endPoint.y - startPoint.y) / 2.0f) + cnt * ABS_SHIFT /** (int)Math.signum(yDelta)*/ ; Point p = new Point(startPoint.x, y); res.add(p); p = new Point(endPoint.x, y); res.add(p); } } else if (startHorizontal) { Point p = new Point(endPoint.x, startPoint.y); res.add(p); } else if (endHorizontal) { Point p = new Point(startPoint.x, endPoint.y); res.add(p); } } res.add(endPoint); return res; } static public void rearrangeAllConnections(final ContainerShape cs, final IJPAEditorFeatureProvider fp, final boolean selfOnly) { TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(cs); ted.getCommandStack().execute(new RecordingCommand(ted) { @Override protected void doExecute() { List<Anchor> anchorsFrom = getAnchors(cs); for (Anchor anchorFrom : anchorsFrom) { Collection<Connection> outgoingConnections = anchorFrom.getOutgoingConnections(); Collection<Connection> incomingConnections = anchorFrom.getIncomingConnections(); Set<Set<Connection>> sets = new HashSet<Set<Connection>>(); Iterator<Connection> it = outgoingConnections.iterator(); while (it.hasNext()) addConnection(sets, it.next(), selfOnly); it = incomingConnections.iterator(); while (it.hasNext()) addConnection(sets, it.next(), selfOnly); Iterator<Set<Connection>> setsIter = sets.iterator(); while (setsIter.hasNext()) { Set<Connection> set = setsIter.next(); int cnt = 0; int setSize = set.size(); Iterator<Connection> cIter = set.iterator(); while (cIter.hasNext()) { Connection c = cIter.next(); Object o = fp.getBusinessObjectForPictogramElement(c); if (!(o instanceof IRelation) && !(o instanceof HasReferanceRelation) && !(o instanceof IsARelation)) continue; boolean isSelfConnection = false; if (o instanceof IRelation) { IRelation rel = (IRelation) o; isSelfConnection = rel.getOwner() == rel.getInverse(); } rearrangeConnection(c, cnt, setSize, isSelfConnection); cnt++; } } } } }); } static private boolean areConnectionsWithIdenticalEnds(Connection c1, Connection c2) { return ((c1.getStart() == c2.getStart()) && (c1.getEnd() == c2.getEnd())) || ((c1.getStart() == c2.getEnd()) && (c1.getEnd() == c2.getStart())); } static private boolean connectionBelongsToSet(Connection c, Set<Connection> s) { if (s.isEmpty()) return false; Connection example = s.iterator().next(); return areConnectionsWithIdenticalEnds(c, example); } static private int getNumberOfConnectionsWithSameEndsAs(Connection c) { Anchor from = c.getStart(); Anchor to = c.getEnd(); Collection<Connection> cs1 = from.getOutgoingConnections(); Collection<Connection> cs2 = to.getOutgoingConnections(); int cnt = 0; Iterator<Connection> it = cs1.iterator(); while (it.hasNext()) { Connection con = it.next(); if (con.getEnd() == to) cnt++; } if (from == to) return cnt; it = cs2.iterator(); while (it.hasNext()) { Connection con = it.next(); if (con.getEnd() == from) cnt++; } return cnt; } private static void addConnection(Set<Set<Connection>> sets, Connection c, boolean selfOnly) { if (sets == null) throw new NullPointerException("'sets' parameter should not be null"); //$NON-NLS-1$ if (selfOnly && (c.getStart() != c.getEnd())) return; Iterator<Set<Connection>> setsIter = sets.iterator(); while (setsIter.hasNext()) { Set<Connection> set = setsIter.next(); if (connectionBelongsToSet(c, set)) { sets.remove(set); set.add(c); sets.add(set); return; } } Set<Connection> newSet = new HashSet<Connection>(); newSet.add(c); sets.add(newSet); } static private void rearrangeConnection(Connection connection, int cnt, int connectionsNum, boolean selfRelation) { FreeFormConnection c = (FreeFormConnection) connection; rearrangeConnectionBendPoints(c, cnt, connectionsNum, selfRelation); rearrangeConnectionDecoratorsLocation(c, cnt, connectionsNum); } static private void rearrangeConnectionBendPoints(FreeFormConnection c, int cnt, int connectionsNum, boolean selfRelation) { List<org.eclipse.graphiti.mm.algorithms.styles.Point> oldPts = c.getBendpoints(); List<org.eclipse.swt.graphics.Point> newPts = JPAEditorUtil.createBendPointList(c, cnt, connectionsNum, selfRelation); if (newPts == null) return; for (int i = 0; i < Math.min(oldPts.size(), newPts.size()); i++) { oldPts.set(i, Graphiti.getGaService().createPoint(/*c, */newPts.get(i).x, newPts.get(i).y)); } int diff = oldPts.size() - newPts.size(); if (diff > 0) { for (int i = oldPts.size() - 1; i >= newPts.size(); i--) oldPts.remove(i); } else if (diff < 0) { for (int i = oldPts.size(); i < newPts.size(); i++) oldPts.add(Graphiti.getGaService().createPoint(/*c, */newPts.get(i).x, newPts.get(i).y)); } } static private void rearrangeConnectionDecoratorsLocation(FreeFormConnection c, int cnt, int connectionsNum) { Collection<ConnectionDecorator> dcrs = c.getConnectionDecorators(); int len = JPAEditorUtil.calcConnectionLength(c); for (ConnectionDecorator dcr : dcrs) { GraphicsAlgorithm ga = dcr.getGraphicsAlgorithm(); if (ga instanceof Text) { if (Math.abs(dcr.getLocation() - 0.5) < 0.0001) continue; Point pt = recalcTextDecoratorPosition(c, dcr); Graphiti.getGaService().setLocation(ga, pt.x, pt.y, false); continue; } if (dcr.getLocation() < 0.5) { Graphiti.getGaService().setLocation(dcr.getGraphicsAlgorithm(), Math.round(len / 10), 0); } else { Graphiti.getGaService().setLocation(dcr.getGraphicsAlgorithm(), Math.round(-len / 10), 0); } } } public static Point recalcTextDecoratorPosition(FreeFormConnection c, ConnectionDecorator dcr) { int CORR = 5; int TXT_HEIGHT = 8; double location = dcr.getLocation(); RelEndDir relEndDir = (location < 0.5) ? JPAEditorUtil.getConnectionStartDir(c) : JPAEditorUtil.getConnectionEndDir(c); Text txt = (Text) dcr.getGraphicsAlgorithm(); int TXT_WIDTH = txt.getValue().length() * 6; boolean isCardinality = JPAEditorConstants.CARDINALITY_LABELS.contains(txt.getValue()); int x = 0; int y = 0; if (relEndDir.equals(RelEndDir.LEFT)) { x = CORR + (isCardinality ? 2 : 12); y = isCardinality ? (-CORR - 3 - TXT_HEIGHT) : CORR - 3; } else if (relEndDir.equals(RelEndDir.RIGHT)) { x = -TXT_WIDTH; y = isCardinality ? (-CORR - 3 - TXT_HEIGHT) : CORR - 3; } else if (relEndDir.equals(RelEndDir.UP)) { x = isCardinality ? (-CORR - TXT_WIDTH) : CORR; y = isCardinality ? CORR : CORR + TXT_HEIGHT + 2; } else if (relEndDir.equals(RelEndDir.DOWN)) { x = isCardinality ? (-CORR - TXT_WIDTH) : CORR; y = -CORR - (isCardinality ? TXT_HEIGHT : (TXT_HEIGHT + 2) << 1); } return new Point(x, y); } public static String formTableName(PersistentType jpt) { IProject project = jpt.getJpaProject().getProject(); Properties props = JPADiagramPropertyPage.loadProperties(project); String tableNamePrefix = JPADiagramPropertyPage.getDefaultTablePrefixName(project, props); String shortEntityName = JPAEditorUtil.returnSimpleName(JpaArtifactFactory.instance().getEntityName(jpt)); if (tableNamePrefix.length() == 0) return shortEntityName; return tableNamePrefix + shortEntityName.toUpperCase(Locale.ENGLISH); } static private List<Anchor> getAnchors(ContainerShape containerShape) { List<Anchor> ret = new ArrayList<Anchor>(); ret.addAll(containerShape.getAnchors()); List<Shape> children = containerShape.getChildren(); for (Shape shape : children) { if (shape instanceof ContainerShape) { ret.addAll(getAnchors((ContainerShape) shape)); } else { ret.addAll(shape.getAnchors()); } } return ret; } static private RelEndDir getConnectionStartDir(FreeFormConnection c) { EList<org.eclipse.graphiti.mm.algorithms.styles.Point> pts = c.getBendpoints(); return getConnectionEndDir(pts.get(0), pts.get(1)); } static private RelEndDir getConnectionEndDir(FreeFormConnection c) { List<org.eclipse.graphiti.mm.algorithms.styles.Point> pts = c.getBendpoints(); return getConnectionEndDir(pts.get(pts.size() - 1), pts.get(pts.size() - 2)); } static private RelEndDir getConnectionEndDir(org.eclipse.graphiti.mm.algorithms.styles.Point ptEnd, org.eclipse.graphiti.mm.algorithms.styles.Point ptNextToEnd) { if (ptEnd.getX() == ptNextToEnd.getX()) { return (ptNextToEnd.getY() > ptEnd.getY()) ? RelEndDir.UP : RelEndDir.DOWN; } else { return (ptNextToEnd.getX() > ptEnd.getX()) ? RelEndDir.LEFT : RelEndDir.RIGHT; } } static public void organizeImports(ICompilationUnit cu, IWorkbenchSite ws) { OrganizeImportsAction action = new OrganizeImportsAction(ws); action.run(cu); } static public void formatCode(ICompilationUnit cu, IWorkbenchSite ws) { FormatAllAction action = new FormatAllAction(ws); action.run(new StructuredSelection(cu)); } static public String generateUniquePersistentObjectName(JpaProject jpaProject, String pack, String objectTypeName, IJPAEditorFeatureProvider fp) { String NAME = pack + objectTypeName; String name = null; HashSet<String> JPAProjectEntityNames = getEntityNames(jpaProject); HashSet<String> JPAProjectEntitySimpleNames = getEntitySimpleNames(jpaProject); for (int i = 1; i < 100000000; i++) { name = NAME + i; if ((!fp.hasObjectWithName(name)) && !JPAProjectEntityNames.contains(name.toLowerCase(Locale.ENGLISH)) && !JPAProjectEntitySimpleNames .contains(JPAEditorUtil.returnSimpleName(name).toLowerCase(Locale.ENGLISH)) && !isJavaFileInProject(jpaProject.getProject(), name, pack)) break; } return name; } static public IFile createEntityInProject(IProject project, String entityName, PersistentType mappedSuperclass) throws Exception { IFolder folder = getPackageFolder(project); return createEntity(project, folder, entityName, true, mappedSuperclass.getName(), JpaArtifactFactory.instance().getMappedSuperclassPackageDeclaration(mappedSuperclass), JpaArtifactFactory.instance().generateIdName(mappedSuperclass), JpaArtifactFactory.instance().hasOrInheritsPrimaryKey(mappedSuperclass)); } static public IFile createEntityInProject(IProject project, String entityName, IPreferenceStore jpaPreferenceStore, boolean isMappedSuperclassChild, String mappedSuperclassName, String mappedSuperclassPackage, String idName, boolean hasPrimaryKey) throws Exception { IFolder folder = getPackageFolder(project); return createEntity(project, folder, entityName, isMappedSuperclassChild, mappedSuperclassName, mappedSuperclassPackage, idName, hasPrimaryKey); } @SuppressWarnings("deprecation") private static IFolder getPackageFolder(IProject project) throws JavaModelException { IJavaProject javaProject = JavaCore.create(project); IPackageFragmentRoot[] packageFragmentRoots = new IPackageFragmentRoot[0]; final IClasspathEntry[] classpathEntries = javaProject.getRawClasspath(); for (IClasspathEntry classpathEntry : classpathEntries) { if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { packageFragmentRoots = javaProject.getPackageFragmentRoots(classpathEntry); break; } } IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[0]; Properties props = JPADiagramPropertyPage.loadProperties(project); IPackageFragment packageFragment = packageFragmentRoot .getPackageFragment(JPADiagramPropertyPage.getDefaultPackage(project, props)); if (packageFragment.exists() == false) { packageFragment = packageFragmentRoot.createPackageFragment( JPADiagramPropertyPage.getDefaultPackage(project, props), true, new NullProgressMonitor()); } IFolder folder = (IFolder) packageFragment.getCorrespondingResource(); return folder; } public static IFile createMappedSuperclassInProject(IProject project, String mappedSuperclassName) throws Exception { IFolder folder = getPackageFolder(project); String mappedSuperclassShortName = mappedSuperclassName .substring(mappedSuperclassName.lastIndexOf('.') + 1); String content = "package " + JPADiagramPropertyPage.getDefaultPackage(project) + ";\n\n" //$NON-NLS-1$ //$NON-NLS-2$ + "import java.io.Serializable;\n" //$NON-NLS-1$ + "import javax.persistence.*;\n\n" //$NON-NLS-1$ + "@MappedSuperclass \n" //$NON-NLS-1$ + "public abstract class " + mappedSuperclassShortName + " implements Serializable {\n\n" //$NON-NLS-1$ //$NON-NLS-2$ + "private static final long serialVersionUID = 1L;\n" //$NON-NLS-1$ + "}"; //$NON-NLS-1$ return createClassInProject(project, folder, mappedSuperclassShortName, content); } public static IFile createEmbeddableInProject(IProject project, String embeddableName) throws Exception { IFolder folder = getPackageFolder(project); String embeddableShortName = embeddableName.substring(embeddableName.lastIndexOf('.') + 1); String content = "package " + JPADiagramPropertyPage.getDefaultPackage(project) + ";\n\n" //$NON-NLS-1$ //$NON-NLS-2$ + "import javax.persistence.*;\n\n" //$NON-NLS-1$ + "import java.io.Serializable;\n\n" //$NON-NLS-1$ + "@Embeddable \n" //$NON-NLS-1$ + "public class " + embeddableShortName + " implements Serializable {\n\n" //$NON-NLS-1$ //$NON-NLS-2$ + "private static final long serialVersionUID = 1L;\n\n" //$NON-NLS-1$ + "}"; //$NON-NLS-1$ return createClassInProject(project, folder, embeddableShortName, content); } @SuppressWarnings("deprecation") static private boolean isJavaFileInProject(IProject project, String entityName, String defaultEntityPacakage) { IJavaProject javaProject = JavaCore.create(project); IPackageFragmentRoot[] packageFragmentRoots = new IPackageFragmentRoot[0]; IClasspathEntry[] classpathEntries = null; try { classpathEntries = javaProject.getRawClasspath(); } catch (JavaModelException e) { JPADiagramEditorPlugin.logError("Cannot obtain the classpath", e); //$NON-NLS-1$ return false; } for (IClasspathEntry classpathEntry : classpathEntries) { if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { packageFragmentRoots = javaProject.getPackageFragmentRoots(classpathEntry); break; } } IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[0]; IPackageFragment packageFragment = packageFragmentRoot .getPackageFragment(JPADiagramPropertyPage.getDefaultPackage(project)); if (!packageFragment.exists()) return false; IFolder folder = null; try { folder = (IFolder) packageFragment.getCorrespondingResource(); } catch (JavaModelException e) { JPADiagramEditorPlugin.logError("Cannot obtain the folder", e); //$NON-NLS-1$ return false; } if (!folder.exists()) return false; String entityShortName = entityName.substring(entityName.lastIndexOf('.') + 1); IFile file = folder.getFile(entityShortName + ".java"); //$NON-NLS-1$ return file.exists(); } static public String produceUniqueAttributeName(PersistentType jpt, String attributeNameCandidate) { String name = attributeNameCandidate; for (int i = 1; i < 100000000; i++) { if (jpt.getAttributeNamed(name) == null) return name; name = attributeNameCandidate + "_" + i; //$NON-NLS-1$ } return name; } static public String produceUniqueAttributeName(PersistentType jpt, String forbiddenName, String attributeNameCandidate) { String name = attributeNameCandidate; for (int i = 1; i < 100000000; i++) { if ((jpt.getAttributeNamed(name) == null) && !name.equals(forbiddenName)) return name; name = attributeNameCandidate + "_" + i; //$NON-NLS-1$ } return name; } public static boolean isEntityOpenElsewhere(PersistentType jpt, boolean checkDirty) { IEditorReference[] edRefs = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .getEditorReferences(); for (int i = 0; i < edRefs.length; i++) { IEditorPart ed = edRefs[i].getEditor(false); if (ed == null) continue; if (checkDirty && !ed.isDirty()) continue; IEditorInput edInp = ed.getEditorInput(); if (FileEditorInput.class.isInstance(edInp)) { FileEditorInput fedInput = (FileEditorInput) edInp; if (fedInput.getFile().equals(jpt.getResource())) { return true; } } } return false; } public static ICompilationUnit getCompilationUnit(PersistentType jpt) { ICompilationUnit unit = jpt.getJavaResourceType().getJavaResourceCompilationUnit().getCompilationUnit(); return unit; } public static ICompilationUnit getCompilationUnit(IFile file) { return EclipseFacade.INSTANCE.getJavaCore().createCompilationUnitFrom(file); } public static void becomeWorkingCopy(ICompilationUnit cu) { try { cu.becomeWorkingCopy(new NullProgressMonitor()); } catch (JavaModelException e) { JPADiagramEditorPlugin.logError("Can't discard the working copy", e); //$NON-NLS-1$ } } public static void discardWorkingCopy(ICompilationUnit cu) { while (cu.isWorkingCopy()) try { cu.discardWorkingCopy(); } catch (JavaModelException e) { JPADiagramEditorPlugin.logError("Can't discard the working copy", e); //$NON-NLS-1$ } } public static void discardWorkingCopyOnce(ICompilationUnit cu) { if (cu.isWorkingCopy()) try { cu.discardWorkingCopy(); } catch (JavaModelException e) { JPADiagramEditorPlugin.logError("Can't discard the working copy", e); //$NON-NLS-1$ } } private static IFile createEntity(IProject project, IFolder folder, String entityName, boolean isMappedSuperclassChild, String mappedSuperclassName, String mappedSuperclassPackage, String idName, boolean hasPrimaryKey) throws Exception { String entityShortName = entityName.substring(entityName.lastIndexOf('.') + 1); Properties props = JPADiagramPropertyPage.loadProperties(project); String tableNamePrefix = JPADiagramPropertyPage.getDefaultTablePrefixName(project, props); String tableName = (tableNamePrefix.length() > 0) ? (tableNamePrefix + entityShortName.toUpperCase(Locale.ENGLISH)) : ""; //$NON-NLS-1$ boolean fieldBasedAccess = JPADiagramPropertyPage.isAccessFieldBased(project, props); String classDeclarationStringContent = null; String importSerializable = ""; //$NON-NLS-1$ if (isMappedSuperclassChild) { String mappedSuperclassShortName = mappedSuperclassName .substring(mappedSuperclassName.lastIndexOf('.') + 1); classDeclarationStringContent = "public class " + entityShortName + " extends " //$NON-NLS-1$//$NON-NLS-2$ + mappedSuperclassShortName + " {\n\n"; //$NON-NLS-1$ } else { classDeclarationStringContent = "public class " + entityShortName + " implements Serializable {\n\n"; //$NON-NLS-1$ //$NON-NLS-2$ importSerializable += "import java.io.Serializable;\n"; //$NON-NLS-1$ } String packageImport = ""; //$NON-NLS-1$ if (mappedSuperclassPackage != null && !mappedSuperclassPackage.equals("") //$NON-NLS-1$ && !(JPADiagramPropertyPage.getDefaultPackage(project, props).equals(mappedSuperclassPackage))) { packageImport = "import " + mappedSuperclassPackage + ".*;"; //$NON-NLS-1$ //$NON-NLS-2$ } String primaryKeyDeclaration = ""; //$NON-NLS-1$ if (!hasPrimaryKey) primaryKeyDeclaration = generatePrimaryKeyDeclaration(fieldBasedAccess, idName); String content = "package " + JPADiagramPropertyPage.getDefaultPackage(project, props) //$NON-NLS-1$ + ";\n\n" //$NON-NLS-1$ + importSerializable + "import javax.persistence.*;\n" //$NON-NLS-1$ + packageImport + "\n\n" //$NON-NLS-1$ + "@Entity \n" //$NON-NLS-1$ + ((tableName.length() > 0) ? ("@Table(name=\"" //$NON-NLS-1$ + tableName + "\")\n") : "") //$NON-NLS-1$ //$NON-NLS-2$ + classDeclarationStringContent + "private static final long serialVersionUID = 1L;\n" //$NON-NLS-1$ + "public " + entityShortName + "() {\n" //$NON-NLS-1$ //$NON-NLS-2$ + "}\n" //$NON-NLS-1$ + primaryKeyDeclaration + "}"; //$NON-NLS-1$ return createClassInProject(project, folder, entityShortName, content); } private static IFile createClassInProject(IProject project, IFolder folder, String classShortName, String content) throws Exception { if (!folder.exists()) { folder.create(true, true, new NullProgressMonitor()); } IFile file = folder.getFile(classShortName + ".java"); //$NON-NLS-1$ if (!file.exists()) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { stream.write(content.getBytes()); stream.flush(); file.create(new ByteArrayInputStream(stream.toByteArray()), true, new NullProgressMonitor()); } finally { stream.close(); } } return file; } static private String generatePrimaryKeyDeclaration(boolean fieldBasedAccess, String primaryKeyName) { String primaryKeyDeclaration = (fieldBasedAccess ? " @Id \n" : "") //$NON-NLS-1$ //$NON-NLS-2$ + " private long " + primaryKeyName + ";\n\n" //$NON-NLS-1$ //$NON-NLS-2$ + (fieldBasedAccess ? "" : " @Id \n") //$NON-NLS-1$ //$NON-NLS-2$ + " public long get" + capitalizeFirstLetter(primaryKeyName) + "() {\n" //$NON-NLS-1$ //$NON-NLS-2$ + " return " + primaryKeyName + ";\n" //$NON-NLS-1$ //$NON-NLS-2$ + " }\n\n" //$NON-NLS-1$ + " public void set" + capitalizeFirstLetter(primaryKeyName) //$NON-NLS-1$ + "(long " + primaryKeyName + ") {\n" //$NON-NLS-1$ //$NON-NLS-2$ + " this." + primaryKeyName + " = " + primaryKeyName + ";\n" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + " }\n\n"; //$NON-NLS-1$ return primaryKeyDeclaration; } static private HashSet<String> getEntityNames(JpaProject jpaProject) { HashSet<String> names = new HashSet<String>(); ListIterator<PersistenceUnit> lit = jpaProject.getContextModelRoot().getPersistenceXml().getRoot() .getPersistenceUnits().iterator(); PersistenceUnit pu = lit.next(); for (ClassRef cf : pu.getClassRefs()) { names.add(cf.getClassName()); } return names; } static private HashSet<String> getEntitySimpleNames(JpaProject jpaProject) { HashSet<String> names = new HashSet<String>(); ListIterator<PersistenceUnit> lit = jpaProject.getContextModelRoot().getPersistenceXml().getRoot() .getPersistenceUnits().iterator(); PersistenceUnit pu = lit.next(); for (ClassRef cf : pu.getClassRefs()) { names.add(returnSimpleName(cf.getClassName()).toLowerCase(Locale.ENGLISH)); } return names; } public static boolean isCardinalityDecorator(ConnectionDecorator cd) { GraphicsAlgorithm ga = cd.getGraphicsAlgorithm(); if (!Text.class.isInstance(ga)) return false; Text txt = (Text) ga; return JPAEditorConstants.CARDINALITY_LABELS.contains(txt.getValue()); } public static String getTooltipText(PersistentAttribute at) { String res = getAttributeTypeName(at); return MessageFormat.format(JPAEditorMessages.JPAEditorUtil_typeTooltipText, new Object[] { res }); } static public boolean checkJPAFacetVersion(JpaProject jpaProject, String version) { if (jpaProject != null) { return checkJPAFacetVersion(jpaProject.getProject(), version); } return false; } static public boolean checkJPAFacetVersion(IProject project, String version) { IFacetedProject fproj = null; try { fproj = ProjectFacetsManager.create(project); } catch (CoreException e) { JPADiagramEditorPlugin.logError("Could not create faceted project from " + project.getName(), e); //$NON-NLS-1$ } Set<IProjectFacetVersion> projFacets = fproj.getProjectFacets(); Iterator<IProjectFacetVersion> it = projFacets.iterator(); while (it.hasNext()) { IProjectFacetVersion fv = it.next(); if (fv.getProjectFacet().getId().equals(JpaProject.FACET_ID)) { return fv.getVersionString().equals(version); } } return false; } static public String getPrimitiveWrapper(String primitive) { return JPAEditorConstants.PRIMITIVE_TO_WRAPPER.get(primitive); } static private File getFile(IPath classPathEntry) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IFile f = root.getFile(classPathEntry); if ((f != null) && f.exists()) { URI uri = f.getLocationURI(); if (uri == null) return new File(classPathEntry.toOSString()); File file = new File(uri); return file; } else { return new File(classPathEntry.toOSString()); } } static public boolean isPersistenceProviderLibraryInClasspath(IPath classPathEntry) { try { File f = getFile(classPathEntry); if ((f == null) || !f.exists()) return false; JarFile jar = new JarFile(f); Enumeration<JarEntry> entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); if (entry.getName().equals(PERSISTENCE_PROVIDER_LIBRARY_STRING)) { return true; } } } catch (IOException e) { JPADiagramEditorPlugin.logError(e); } return false; } static public boolean checkIsSetPersistenceProviderLibrary(JpaProject jpaProject) { IJavaProject javaProject = JavaCore.create(jpaProject.getProject()); IJavaElement[] elements = new IJavaElement[] { javaProject }; JavaSearchScope scope = (JavaSearchScope) SearchEngine.createJavaSearchScope(elements); boolean isAdded = false; IPath[] paths = scope.enclosingProjectsAndJars(); for (int i = 1; i < paths.length; i++) { IPath path = paths[i]; if (isPersistenceProviderLibraryInClasspath(path)) { isAdded = true; break; } } return isAdded; } private static String cutOffStringPrefix(String s, String prefix) { if (s.startsWith(prefix)) return s.substring(prefix.length()); return s; } private static String cutOffHeaderDirtyPrefix(String header) { return cutOffStringPrefix(header, JPAEditorConstants.HEADER_PREFIX_DIRTY); } public static boolean areHeadersEqual(String h1, String h2) { h1 = cutOffHeaderDirtyPrefix(h1); h2 = cutOffHeaderDirtyPrefix(h2); return h1.equals(h2); } public static PersistentAttribute addAnnotatedAttribute(PersistentType referencingJPT, PersistentType referencedJPT, boolean isCollection, String mapKeyType) { String name = returnSimpleName(referencedJPT.getName()); String actName = returnSimpleName(JpaArtifactFactory.instance().getEntityName(referencedJPT)); String nameWithNonCapitalLetter = decapitalizeFirstLetter(name); String actNameWithNonCapitalLetter = decapitalizeFirstLetter(actName); if (JpaArtifactFactory.instance().isMethodAnnotated(referencingJPT)) { nameWithNonCapitalLetter = produceValidAttributeName(name); actNameWithNonCapitalLetter = produceValidAttributeName(actName); } nameWithNonCapitalLetter = produceUniqueAttributeName(referencingJPT, nameWithNonCapitalLetter); actNameWithNonCapitalLetter = produceUniqueAttributeName(referencingJPT, actNameWithNonCapitalLetter); return JpaArtifactFactory.instance().addAttribute(referencingJPT, referencedJPT, mapKeyType, nameWithNonCapitalLetter, actNameWithNonCapitalLetter, isCollection); } }