List of usage examples for org.eclipse.jdt.core IClasspathEntry getSourceAttachmentPath
IPath getSourceAttachmentPath();
null
if this classpath entry has no source attachment. From source file:at.bestsolution.javafx.ide.jdt.internal.jdt.CPListElement.java
License:Open Source License
public static CPListElement create(Object parent, IClasspathEntry curr, boolean newElement, IJavaProject project) {/*from w w w . j a va 2s. co m*/ IPath path = curr.getPath(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); // get the resource IResource res = null; boolean isMissing = false; IPath linkTarget = null; switch (curr.getEntryKind()) { case IClasspathEntry.CPE_CONTAINER: try { isMissing = project != null && (JavaCore.getClasspathContainer(path, project) == null); } catch (JavaModelException e) { isMissing = true; } break; case IClasspathEntry.CPE_VARIABLE: IPath resolvedPath = JavaCore.getResolvedVariablePath(path); isMissing = root.findMember(resolvedPath) == null && !resolvedPath.toFile().exists(); break; case IClasspathEntry.CPE_LIBRARY: res = root.findMember(path); if (res == null) { if (!ArchiveFileFilter.isArchivePath(path, true)) { if (root.getWorkspace().validatePath(path.toString(), IResource.FOLDER).isOK() && root.getProject(path.segment(0)).exists()) { res = root.getFolder(path); } } IPath rawPath = path; if (project != null) { IPackageFragmentRoot[] roots = project.findPackageFragmentRoots(curr); if (roots.length == 1) rawPath = roots[0].getPath(); } isMissing = !rawPath.toFile().exists(); // look for external JARs and folders } else if (res.isLinked()) { linkTarget = res.getLocation(); } break; case IClasspathEntry.CPE_SOURCE: path = path.removeTrailingSeparator(); res = root.findMember(path); if (res == null) { if (root.getWorkspace().validatePath(path.toString(), IResource.FOLDER).isOK()) { res = root.getFolder(path); } isMissing = true; } else if (res.isLinked()) { linkTarget = res.getLocation(); } break; case IClasspathEntry.CPE_PROJECT: res = root.findMember(path); isMissing = (res == null); break; } CPListElement elem = new CPListElement(parent, project, curr.getEntryKind(), path, newElement, res, linkTarget); elem.setExported(curr.isExported()); elem.setAttribute(SOURCEATTACHMENT, curr.getSourceAttachmentPath()); elem.setAttribute(OUTPUT, curr.getOutputLocation()); elem.setAttribute(EXCLUSION, curr.getExclusionPatterns()); elem.setAttribute(INCLUSION, curr.getInclusionPatterns()); elem.setAttribute(ACCESSRULES, curr.getAccessRules()); elem.setAttribute(COMBINE_ACCESSRULES, new Boolean(curr.combineAccessRules())); IClasspathAttribute[] extraAttributes = curr.getExtraAttributes(); for (int i = 0; i < extraAttributes.length; i++) { IClasspathAttribute attrib = extraAttributes[i]; CPListElementAttribute attribElem = elem.findAttributeElement(attrib.getName()); if (attribElem == null) { elem.createAttributeElement(attrib.getName(), attrib.getValue(), false); } else { attribElem.setValue(attrib.getValue()); } } elem.setIsMissing(isMissing); return elem; }
From source file:com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer.java
License:Open Source License
@Override public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException { AdtPlugin plugin = AdtPlugin.getDefault(); synchronized (Sdk.getLock()) { boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED; // check if the project has a valid target. IAndroidTarget target = null;// w w w . ja v a2 s .co m if (sdkIsLoaded) { target = Sdk.getCurrent().getTarget(project.getProject()); } if (sdkIsLoaded && target != null) { String[] paths = getTargetPaths(target); IPath android_lib = new Path(paths[CACHE_INDEX_JAR]); IClasspathEntry[] entries = containerSuggestion.getClasspathEntries(); for (int i = 0; i < entries.length; i++) { IClasspathEntry entry = entries[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IPath entryPath = entry.getPath(); if (entryPath != null) { if (entryPath.equals(android_lib)) { IPath entrySrcPath = entry.getSourceAttachmentPath(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); if (entrySrcPath != null) { ProjectHelper.saveStringProperty(root, getAndroidSourceProperty(target), entrySrcPath.toString()); } else { ProjectHelper.saveStringProperty(root, getAndroidSourceProperty(target), null); } IClasspathAttribute[] extraAttributtes = entry.getExtraAttributes(); if (extraAttributtes.length == 0) { ProjectHelper.saveStringProperty(root, PROPERTY_ANDROID_API, NULL_API_URL); } for (int j = 0; j < extraAttributtes.length; j++) { IClasspathAttribute extraAttribute = extraAttributtes[j]; String value = extraAttribute.getValue(); if ((value == null || value.trim().length() == 0) && IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME .equals(extraAttribute.getName())) { value = NULL_API_URL; } if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME .equals(extraAttribute.getName())) { ProjectHelper.saveStringProperty(root, PROPERTY_ANDROID_API, value); } } } } } } rebindClasspathEntries(project.getJavaModel(), containerPath); } } }
From source file:com.android.ide.eclipse.adt.internal.project.LibraryClasspathContainerInitializer.java
License:Open Source License
private static List<IClasspathEntry> convertJarsToClasspathEntries(final IProject iProject, Set<File> jarFiles) { List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(jarFiles.size()); // and process the jar files list, but first sanitize it to remove dups. JarListSanitizer sanitizer = new JarListSanitizer( iProject.getFolder(SdkConstants.FD_OUTPUT).getLocation().toFile(), new AndroidPrintStream(iProject, null /*prefix*/, AdtPlugin.getOutStream())); String errorMessage = null;/*w w w . j a v a 2 s. com*/ try { List<File> sanitizedList = sanitizer.sanitize(jarFiles); for (File jarFile : sanitizedList) { if (jarFile instanceof CPEFile) { CPEFile cpeFile = (CPEFile) jarFile; IClasspathEntry e = cpeFile.getClasspathEntry(); entries.add(JavaCore.newLibraryEntry(e.getPath(), e.getSourceAttachmentPath(), e.getSourceAttachmentRootPath(), e.getAccessRules(), e.getExtraAttributes(), true /*isExported*/)); } else { String jarPath = jarFile.getAbsolutePath(); IPath sourceAttachmentPath = null; IClasspathAttribute javaDocAttribute = null; File jarProperties = new File(jarPath + DOT_PROPERTIES); if (jarProperties.isFile()) { Properties p = new Properties(); InputStream is = null; try { p.load(is = new FileInputStream(jarProperties)); String value = p.getProperty(ATTR_SRC); if (value != null) { File srcPath = getFile(jarFile, value); if (srcPath.exists()) { sourceAttachmentPath = new Path(srcPath.getAbsolutePath()); } } value = p.getProperty(ATTR_DOC); if (value != null) { File docPath = getFile(jarFile, value); if (docPath.exists()) { try { javaDocAttribute = JavaCore.newClasspathAttribute( IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, docPath.toURI().toURL().toString()); } catch (MalformedURLException e) { AdtPlugin.log(e, "Failed to process 'doc' attribute for %s", jarProperties.getAbsolutePath()); } } } } catch (FileNotFoundException e) { // shouldn't happen since we check upfront } catch (IOException e) { AdtPlugin.log(e, "Failed to read %s", jarProperties.getAbsolutePath()); } finally { if (is != null) { try { is.close(); } catch (IOException e) { // ignore } } } } if (javaDocAttribute != null) { entries.add(JavaCore.newLibraryEntry(new Path(jarPath), sourceAttachmentPath, null /*sourceAttachmentRootPath*/, new IAccessRule[0], new IClasspathAttribute[] { javaDocAttribute }, true /*isExported*/)); } else { entries.add(JavaCore.newLibraryEntry(new Path(jarPath), sourceAttachmentPath, null /*sourceAttachmentRootPath*/, true /*isExported*/)); } } } } catch (DifferentLibException e) { errorMessage = e.getMessage(); AdtPlugin.printErrorToConsole(iProject, (Object[]) e.getDetails()); } catch (Sha1Exception e) { errorMessage = e.getMessage(); } processError(iProject, errorMessage, AdtConstants.MARKER_DEPENDENCY, true /*outputToConsole*/); return entries; }
From source file:com.android.ide.eclipse.adt.internal.sourcelookup.AdtSourceLookupDirector.java
License:Open Source License
@Override public void initializeDefaults(ILaunchConfiguration configuration) throws CoreException { dispose();//from w w w . j a v a 2 s .co m setLaunchConfiguration(configuration); String projectName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ if (projectName != null && projectName.length() > 0) { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); if (project != null && project.isOpen()) { ProjectState state = Sdk.getProjectState(project); if (state == null) { initDefaults(); return; } IAndroidTarget target = state.getTarget(); if (target == null) { initDefaults(); return; } String path = target.getPath(IAndroidTarget.ANDROID_JAR); if (path == null) { initDefaults(); return; } IJavaProject javaProject = JavaCore.create(project); if (javaProject != null && javaProject.isOpen()) { IClasspathEntry[] entries = javaProject.getResolvedClasspath(true); IClasspathEntry androidEntry = null; for (int i = 0; i < entries.length; i++) { IClasspathEntry entry = entries[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && path.equals(entry.getPath().toString())) { androidEntry = entry; break; } } if (androidEntry != null) { IPath sourceAttachmentPath = androidEntry.getSourceAttachmentPath(); if (sourceAttachmentPath != null) { String androidSrc = sourceAttachmentPath.toString(); if (androidSrc != null && androidSrc.trim().length() > 0) { File srcFile = new File(androidSrc); ISourceContainer adtContainer = null; if (srcFile.isFile()) { adtContainer = new ExternalArchiveSourceContainer(androidSrc, true); } if (srcFile.isDirectory()) { adtContainer = new DirectorySourceContainer(srcFile, false); } if (adtContainer != null) { ISourceContainer defaultContainer = new DefaultSourceContainer(); setSourceContainers(new ISourceContainer[] { adtContainer, defaultContainer }); initializeParticipants(); return; } } } } } } } initDefaults(); }
From source file:com.android.ide.eclipse.auidt.internal.project.AndroidClasspathContainerInitializer.java
License:Open Source License
@Override public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException { AdtPlugin plugin = AdtPlugin.getDefault(); synchronized (Sdk.getLock()) { boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED; // check if the project has a valid target. IAndroidTarget target = null;//from ww w . j a v a2s . c o m if (sdkIsLoaded) { target = Sdk.getCurrent().getTarget(project.getProject()); } if (sdkIsLoaded && target != null) { String[] paths = getTargetPaths(target); IPath android_lib = new Path(paths[CACHE_INDEX_JAR]); IClasspathEntry[] entries = containerSuggestion.getClasspathEntries(); for (int i = 0; i < entries.length; i++) { IClasspathEntry entry = entries[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IPath entryPath = entry.getPath(); if (entryPath != null) { if (entryPath.equals(android_lib)) { IPath entrySrcPath = entry.getSourceAttachmentPath(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); if (entrySrcPath != null) { ProjectHelper.saveStringProperty(root, getAndroidSourceProperty(target), entrySrcPath.toString()); } else { ProjectHelper.saveStringProperty(root, getAndroidSourceProperty(target), null); } IClasspathAttribute[] extraAttributtes = entry.getExtraAttributes(); if (extraAttributtes.length == 0) { ProjectHelper.saveStringProperty(root, PROPERTY_ANDROID_API, NULL_API_URL); } for (int j = 0; j < extraAttributtes.length; j++) { IClasspathAttribute extraAttribute = extraAttributtes[j]; String value = extraAttribute.getValue(); if ((value == null || value.trim().length() == 0) && IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME .equals(extraAttribute.getName())) { value = NULL_API_URL; } if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME .equals(extraAttribute.getName())) { ProjectHelper.saveStringProperty(root, PROPERTY_ANDROID_API, value); } } } } } } rebindClasspathEntries(project.getJavaModel(), containerPath); } } }
From source file:com.android.ide.eclipse.auidt.internal.sourcelookup.AdtSourceLookupDirector.java
License:Open Source License
@Override public void initializeDefaults(ILaunchConfiguration configuration) throws CoreException { dispose();/*from ww w .j a v a2s .co m*/ setLaunchConfiguration(configuration); String projectName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$ if (projectName != null && projectName.length() > 0) { IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); if (project != null && project.isOpen()) { ProjectState state = Sdk.getProjectState(project); if (state == null) { initDefaults(); return; } IAndroidTarget target = state.getTarget(); if (target == null) { initDefaults(); return; } // String path = target.getPath(IAndroidTarget.ANDROID_JAR); String path = AdtPlugin.getAuidtJar(); if (path == null) { initDefaults(); return; } IJavaProject javaProject = JavaCore.create(project); if (javaProject != null && javaProject.isOpen()) { IClasspathEntry[] entries = javaProject.getResolvedClasspath(true); IClasspathEntry androidEntry = null; for (int i = 0; i < entries.length; i++) { IClasspathEntry entry = entries[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && path.equals(entry.getPath().toString())) { androidEntry = entry; break; } } if (androidEntry != null) { IPath sourceAttachmentPath = androidEntry.getSourceAttachmentPath(); if (sourceAttachmentPath != null) { String androidSrc = sourceAttachmentPath.toString(); if (androidSrc != null && androidSrc.trim().length() > 0) { File srcFile = new File(androidSrc); ISourceContainer adtContainer = null; if (srcFile.isFile()) { adtContainer = new ExternalArchiveSourceContainer(androidSrc, true); } if (srcFile.isDirectory()) { adtContainer = new DirectorySourceContainer(srcFile, false); } if (adtContainer != null) { ISourceContainer defaultContainer = new DefaultSourceContainer(); setSourceContainers(new ISourceContainer[] { adtContainer, defaultContainer }); initializeParticipants(); return; } } } } } } } initDefaults(); }
From source file:com.codenvy.ide.ext.java.server.internal.core.DeltaProcessingState.java
License:Open Source License
private HashMap[] getRootInfos(boolean usePreviousSession) { HashMap newRoots = new HashMap(); HashMap newOtherRoots = new HashMap(); HashMap newSourceAttachments = new HashMap(); HashMap newProjectDependencies = new HashMap(); IJavaModel model = manager.getJavaModel(); IJavaProject[] projects;/*from w ww . j a v a2 s. c o m*/ try { projects = model.getJavaProjects(); } catch (JavaModelException e) { // nothing can be done return null; } for (int i = 0, length = projects.length; i < length; i++) { JavaProject project = (JavaProject) projects[i]; IClasspathEntry[] classpath; try { // if (usePreviousSession) { // PerProjectInfo perProjectInfo = project.getPerProjectInfo(); // project.resolveClasspath(perProjectInfo, true/*use previous session values*/, false/*don't add classpath change*/); // classpath = perProjectInfo.resolvedClasspath; // } else { classpath = project.getResolvedClasspath(); // } } catch (JavaModelException e) { // continue with next project continue; } for (int j = 0, classpathLength = classpath.length; j < classpathLength; j++) { IClasspathEntry entry = classpath[j]; if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { IJavaProject key = model.getJavaProject(entry.getPath().segment(0)); // TODO (jerome) reuse handle IJavaProject[] dependents = (IJavaProject[]) newProjectDependencies.get(key); if (dependents == null) { dependents = new IJavaProject[] { project }; } else { int dependentsLength = dependents.length; System.arraycopy(dependents, 0, dependents = new IJavaProject[dependentsLength + 1], 0, dependentsLength); dependents[dependentsLength] = project; } newProjectDependencies.put(key, dependents); continue; } // root path IPath path = entry.getPath(); if (newRoots.get(path) == null) { newRoots.put(path, new DeltaProcessor.RootInfo(project, path, ((ClasspathEntry) entry).fullInclusionPatternChars(), ((ClasspathEntry) entry).fullExclusionPatternChars(), entry.getEntryKind())); } else { ArrayList rootList = (ArrayList) newOtherRoots.get(path); if (rootList == null) { rootList = new ArrayList(); newOtherRoots.put(path, rootList); } rootList.add(new DeltaProcessor.RootInfo(project, path, ((ClasspathEntry) entry).fullInclusionPatternChars(), ((ClasspathEntry) entry).fullExclusionPatternChars(), entry.getEntryKind())); } // source attachment path if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue; String propertyString = null; // try { // propertyString = Util.getSourceAttachmentProperty(path); // } catch (JavaModelException e) { // e.printStackTrace(); // } IPath sourceAttachmentPath; if (propertyString != null) { int index = propertyString.lastIndexOf(PackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER); sourceAttachmentPath = (index < 0) ? new Path(propertyString) : new Path(propertyString.substring(0, index)); } else { sourceAttachmentPath = entry.getSourceAttachmentPath(); } if (sourceAttachmentPath != null) { newSourceAttachments.put(sourceAttachmentPath, path); } } } return new HashMap[] { newRoots, newOtherRoots, newSourceAttachments, newProjectDependencies }; }
From source file:com.drgarbage.bytecodevisualizer.editors.NoSourceViewer.java
License:Apache License
private void createSourceAttachmentControls(Composite composite, IPackageFragmentRoot root) throws JavaModelException { IClasspathEntry entry; try {// w w w.ja va2s . c om entry = root.getRawClasspathEntry(); } catch (JavaModelException ex) { if (ex.isDoesNotExist()) entry = null; else throw ex; } IPath containerPath = null; if (entry == null || root.getKind() != IPackageFragmentRoot.K_BINARY) { String s = CoreMessages.SourceAttachmentForm_message_noSource; createLabel(composite, MessageFormat.format(s, new Object[] { fFile.getElementName() })); return; } IJavaProject jproject = root.getJavaProject(); if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) { containerPath = entry.getPath(); ClasspathContainerInitializer initializer = JavaCore .getClasspathContainerInitializer(containerPath.segment(0)); IClasspathContainer container = JavaCore.getClasspathContainer(containerPath, jproject); if (initializer == null || container == null) { createLabel(composite, MessageFormat.format(CoreMessages.SourceAttachmentForm_cannotconfigure, new Object[] { containerPath.toString() })); return; } String containerName = container.getDescription(); IStatus status = initializer.getSourceAttachmentStatus(containerPath, jproject); if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_NOT_SUPPORTED) { createLabel(composite, MessageFormat.format(CoreMessages.SourceAttachmentForm_notsupported, new Object[] { containerName })); return; } if (status.getCode() == ClasspathContainerInitializer.ATTRIBUTE_READ_ONLY) { createLabel(composite, MessageFormat.format(CoreMessages.SourceAttachmentForm_readonly, new Object[] { containerName })); return; } entry = JavaModelUtil.findEntryInContainer(container, root.getPath()); Assert.isNotNull(entry); } Button button; String msg = null; String btnText = null; IPath path = entry.getSourceAttachmentPath(); if (path == null || path.isEmpty()) { msg = MessageFormat.format(CoreMessages.SourceAttachmentForm_message_noSourceAttachment, new Object[] { root.getElementName() }); btnText = CoreMessages.SourceAttachmentForm_button_attachSource; } else { msg = MessageFormat.format(CoreMessages.SourceAttachmentForm_message_noSourceInAttachment, new Object[] { fFile.getElementName() }); btnText = CoreMessages.SourceAttachmentForm_button_changeAttachedSource; } createLabel(composite, msg); createLabel(composite, CoreMessages.SourceAttachmentForm_message_pressButtonToAttach); createLabel(composite, null); button = createButton(composite, btnText); button.addSelectionListener(createButtonListener(entry, containerPath, jproject)); }
From source file:com.google.cloud.tools.eclipse.appengine.libraries.AppEngineLibraryContainerInitializerTest.java
License:Apache License
/** * This test relies on the {@link TestAppEngineLibraryContainerInitializer} defined in the fragment.xml for * <code>TEST_CONTAINER_PATH</code>. When the test is launched, the Platform will try to initialize the container * defined for the test project (field <code>testProject</code>), but due to the empty implementation of * {@link TestAppEngineLibraryContainerInitializer#initialize(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)} * the container will remain unresolved. * Then the {@link AppEngineLibraryContainerInitializer} instance created in this method will initialize the container * and the test will verify it./* w ww .j a v a2 s. c o m*/ * This approach is required by the fact that the production {@link AppEngineLibraryContainerInitializer} is defined * in the host project's plugin.xml and it is not possible to remove/override it. */ @Test public void testInitialize_resolvesContainerToJar() throws CoreException { AppEngineLibraryContainerInitializer containerInitializer = new AppEngineLibraryContainerInitializer( new IConfigurationElement[] { configurationElement }, libraryFactory, TEST_CONTAINER_PATH, serializer, repositoryService); containerInitializer.initialize(new Path(TEST_LIBRARY_PATH), testProject.getJavaProject()); IClasspathEntry[] resolvedClasspath = testProject.getJavaProject().getResolvedClasspath(false); assertThat(resolvedClasspath.length, is(2)); IClasspathEntry libJar = resolvedClasspath[1]; assertThat(libJar.getPath().toOSString(), is("/test/path/artifactId.jar")); assertThat(libJar.getSourceAttachmentPath().toOSString(), is("/test/path/artifactId-sources.jar")); }
From source file:com.google.cloud.tools.eclipse.appengine.libraries.AppEngineLibraryContainerInitializerTest.java
License:Apache License
@Test public void testInitialize_libraryFactoryErrorDoesNotPreventOtherLibraries() throws Exception { Library library = new Library(TEST_LIBRARY_ID); library.setLibraryFiles(//from w w w .j a v a 2 s. co m Collections.singletonList(new LibraryFile(new MavenCoordinates("groupId", "artifactId")))); // this will override what is set in setupLibraryFactory() when setUp() is executed doThrow(LibraryFactoryException.class).doReturn(library).when(libraryFactory) .create(any(IConfigurationElement.class)); AppEngineLibraryContainerInitializer containerInitializer = new AppEngineLibraryContainerInitializer( new IConfigurationElement[] { configurationElement, configurationElement }, libraryFactory, TEST_CONTAINER_PATH, serializer, repositoryService); containerInitializer.initialize(new Path(TEST_LIBRARY_PATH), testProject.getJavaProject()); IClasspathEntry[] resolvedClasspath = testProject.getJavaProject().getResolvedClasspath(false); assertThat(resolvedClasspath.length, is(2)); IClasspathEntry libJar = resolvedClasspath[1]; assertThat(libJar.getPath().toOSString(), is("/test/path/artifactId.jar")); assertThat(libJar.getSourceAttachmentPath().toOSString(), is("/test/path/artifactId-sources.jar")); }